Note the following details of the code protection feature on Microchip devices:
YSTEM
CERTIFIED BY DNV
== ISO/TS 16949==
•Microchip products meet the specification contained in their particular Microchip Data Sheet.
•Microchip believes that its family of products is one of the most secure families of its kind on the market today, when used in the
intended manner and under normal conditions.
•There are dishonest and possibly illegal methods used to breach the code protection feature. All of these methods, to our
knowledge, require using the Microchip products in a manner outside the operating specifications contained in Microchip’s Data
Sheets. Most likely, the person doing so is engaged in theft of intellectual property.
•Microchip is willing to work with the customer who is concerned about the integrity of their code.
•Neither Microchip nor any other semiconductor manufacturer can guarantee the security of their code. Code protection does not
mean that we are guaranteeing the product as “unbreakable.”
Code protection is constantly evolving. We at Microchip are committed to continuously improving the code protection features of our
products. Attempts to break Microchip’s code protection feature may be a violation of the Digital Millennium Copyright Act. If such acts
allow unauthorized access to your software or other copyrighted work, you may have a right to sue for relief under that Act.
Information contained in this publication regarding device
applications and t he lik e is provided only for your convenience
and may be su perseded by upda t es . It is y our responsibility to
ensure that your application meets with your specifications.
MICROCHIP MAKES NO REPRESENTATIONS OR
WARRANTIES OF ANY KIND WHETHER EXPRESS OR
IMPLIED, WRITTEN OR ORAL, STATUTORY OR
OTHERWISE, RELATED TO THE INFORMATION,
INCLUDING BUT NOT LIMITED TO ITS CONDITION,
QUALITY, PERFORMANCE, MERCHANTABILITY OR
FITNESS FOR PURPOSE. Microchip disclaims all liability
arising from this information and its use. Use of Microchip
devices in life supp ort and/or safety ap plications is entir ely at
the buyer’s risk, and the buyer agrees to defend, indemnify and
hold harmless M icrochip from any and all dama ges, claims,
suits, or expenses re sulting from such use. No licens es are
conveyed, implicitly or otherwise, under any Microchip
intellectual property rights.
Trademarks
The Microchip name and logo, the Microchip logo, dsPIC,
K
logo, rfPIC and UNI/O are registered trademarks of
Microchip Technology Incorporated in the U.S.A. and other
countries.
FilterLab, Hampshire, HI-TECH C, Linear Active Thermistor,
MXDEV, MXLAB, SEEVAL and The Embedded Control
Solutions Company are registered trademarks of Microchip
Technology Incorporated in the U.S.A.
Analog-for-the-Digital Age, Application Maestro, chipKIT,
chipKIT logo, CodeGuard, dsPICDEM, dsPICDEM.net,
dsPICworks, dsSPEAK, ECAN, ECONOMONITOR,
FanSense, HI-TIDE, In-Circuit Serial Programming, ICSP,
Mindi, MiWi, MPASM, MPLAB Certified logo, MPLIB,
MPLINK, mTouch, Omniscient Code Generation, PICC,
PICC-18, PICDEM, PICDEM.net, PICkit, PICtail, REAL ICE,
rfLAB, Select Mode, Total Endurance, TSHARC,
UniWinDriver, WiperLock and ZENA are trademarks of
Microchip Technology Incorporated in the U.S.A. and other
countries.
SQTP is a service mark of Microchip Technology Incorporated
in the U.S.A.
All other trademarks mentioned herein are property of their
respective companies.
Microchip received ISO/TS-16949:2009 certification for its worldwide
headquarters, design and wafer fabrication facilities in Chandler and
Tempe, Arizona; Gresham, Oregon and design centers in California
and India. The Company’s quality system processes and procedures
are for its PIC
devices, Serial EEPROMs, microperipherals, nonvolatile memory and
analog products. In addition, Microchip’s quality system for the design
and manufacture of development systems is ISO 9001:2000 certified.
Index ...........................................................................................................................327
Worldwide Sales and Service ...................................................................................338
DS52071B-page 10 2012 Microchip Technology Inc.
MPLAB® XC16 C COMPILER
USER’S GUIDE
Preface
NOTICE TO CUSTOMERS
All documentation becomes dated, and this manual is no exception. Microchip tools and documentation are constantly evolving to meet customer needs, so some actual dialogs and/or tool descriptions
may differ from those in this document.
For the most up-to-date information on development tools, see the MPLAB
Help. Select the Help menu and then “Topics” or “Help Contents” to open a list of available Help files.
For the most current PDFs, please refer to our web site (http://www.microchip.com). Documents are
identified by “DSXXXXXA”, where “XXXXX” is the document number and “A” is the revision level of
the document. This number is located on the bottom of each page, in front of the page number.
INTRODUCTION
MPLAB XC16 C Compiler documentation and support information is discussed in the
sections below:
• Document Layout
• Conventions Used
• Recommended Reading
• myMicrochip Personalized Notification Service
• The Microchip Web Site
• Microchip Forums
• Customer Support
®
IDE or MPLAB X I DE
2012 Microchip Technology Inc.DS52071B-page 11
MPLAB® XC16 C Compiler User’s Guide
DOCUMENT LAYOUT
This document describes how to use GNU language tools to write code for 16-bit
applications. The document layout is as follows:
• Chapter 1. “Compiler Overvie w ” – describes the compiler, development tools
and feature set.
• Chapter 3. “Compiler Command-Line Driver” – describes how to use the
compiler from the command line.
• Chapter 5. “Differences Between MPLAB XC16 and ANSI C” – describes the
differences between the C language supported by the compiler syntax and the
standard ANSI-89 C.
• Chapter 4. “Device-Re lat ed Fea tures” – describes the compiler header and
register definition files, as well as how to use with SFRs.
• Chapter 6. “Supported Data Types and Variables” – describes the compiler
integer, floating point and pointer data types.
• Chapter 7. “Memory Allocation and Access” – describes the compiler run-time
model, including information on sections, initialization, memory models, the
software stack and much more.
• Chapter 8. “Operators and Statements” – discusses operators and statements.
• Chapter 9. “Registe r Usage” – explains how to access and use SFRs.
• Chapter 10. “Functions” – details available functions.
• Chapter 11. “Interrupts” – describes how to use interrupts.
• Chapter 12. “Main, Runtime Startup and Reset” – describes important
elements of C code.
• Chapter 14. “Libr ary Routi nes” – explains how to use libraries.
• Chapter 13. “Mixing C and Assembly Code” – provides guidelines to using the
compiler with 16-bit assembly language modules.
Choice of mut ually exclus ive
arguments; an OR selection
Represents code supplied by
user
Device Dependent.
This feature is not supported
on all devices. Devices supported will be listed in the title
or text.
errorlevel {0|1}
var_name...]
void main (void)
{ ...
}
xmemory attribute
2012 Microchip Technology Inc.DS52071B-page 13
MPLAB® XC16 C Compiler User’s Guide
RECOMMENDED READING
This documentation describes how to use the MPLAB XC16 C Compiler. Other useful
documents are listed below. The following Microchip documents are available and
recommended as supplemental reference resources.
Release Notes (Readme Files)
For the latest information on Microchip tools, read the associated Release Notes
(HTML files) included with the software.
MPLAB
User’s Guide (DS51317)
A guide to using the 16-bit assembler, object linker, object archiver/librarian and various
utilities.
16-Bit Language Tools Libraries (DS51456)
A descriptive listing of libraries available for Microchip 16-bit devices. This includes
standard (including math) libraries and C compiler built-in functions. DSP and 16-bit
peripheral libraries are described in Release Notes provided with each peripheral
library type.
Device-Specific Documentation
The Microchip website contains many documents that describe 16-bit device functions
and features. Among these are:
• Individual and family data sheets
• Family reference manuals
• Programmer’s reference manuals
C Standards Information
®
Assembler, Linker and Utilities for PIC24 MCUs and dsPIC® DSCs
American National Standard for Information Systems – Programming Language – C.
American National Standards Institute (ANSI), 11 West 42nd. Street, New York,
New York, 10036.
This standard specifies the form and establishes the interpretation of programs
expressed in the programming language C. Its purpose is to promote portability,
reliability, maintainability and efficient execution of C language program s on a
variety of computing systems.
C Reference Manuals
Harbison, Samuel P . and Steele, Guy L., C A Reference Manual, Fourth Edition,
Prentice-Hall, Englewood Cliffs, N.J. 07632.
Kernighan, Brian W. and Ritchie, Dennis M., The C Programming Language, Secon d
Kochan, Steven G., Programming In ANSI C, Revised Edition. Hayden Books,
Indianapolis, Indiana 46268.
Plauger, P.J., The Standard C Library, Prentice-Hall, Englewood Cliffs, N.J. 07632.
Van Sickle, Ted., Programming Microcontrollers in C, First Edition. LLH Technology
Publishing, Eagle Rock, Virginia 24085.
DS52071B-page 14 2012 Microchip Technology Inc.
myMICROCHIP PERSONALIZED NOTIFICATION SERVICE
Microchip's personal notification service helps keep customers current on their
Microchip products of interest. Subscribers will receive e-mail notification whenever
there are changes, updates, revisions or errata related to a specified product family or
development tool.
Please visit http://www.microchip.com/pcn to begin the registration process and select
your preferences to receive personalized notifications. A FAQ and registration details
are available on the page, which can be opened by selecting the link above.
When you are selecting your preferences, choosing “Development Systems” will pop-
ulate the list with available development tools. The main categories of tools are listed
below:
• Compilers – The latest info rmatio n on Microc hip C comp ilers, as semblers , linker s
and other language tools. These include all MPLAB C compilers; all MPLAB
assemblers (including MPASM™ assembler); all MPLAB linkers (including
MPLINK™ object linker); and all MPLAB librarians (including MPLIB™ object
librarian).
• Emulators – The latest information on Microchip in-circuit emulators.These
include the MPLAB REAL ICE™ and MPLAB ICE 2000 in-circuit emulators
• In-Circuit Debuggers – The latest information on Microchip in-circuit debuggers.
These include the MPLAB ICD 2 and 3 in-circuit debuggers and PICkit™ 2 and 3
debug express.
• MPLAB
the Windows
source, cross-platform Integrated Development Environment. These lists focus on
the IDE, Project Manager, Editor and Simulator, as well as general editing and
debugging features.
• Programmers – The latest information on Microchip programmers. These include
the device (production) programmers MPLAB REAL ICE in-circuit emulator,
MPLAB ICD 3 in-circuit debugger, MPLAB PM3 and development (nonproduction)
programmers MPLAB ICD 2 in-circuit debugger, PICSTART
and 3.
• Starter/Demo Boards – These include MPLAB Starter Kit boards, PICDEM demo
boards, and various other evaluation boards.
®
IDE/MPLAB X IDE – The latest information on Microchip MPLAB IDE,
®
Integrated Development Environment, or MPLAB X IDE, the open
Preface
®
Plus and PICkit 2
THE MICROCHIP WEB SITE
Microchip provides online support via our web site at http://www.microchip.com. This
web site is used as a means to make files and information easily available to
customers. Accessible by using your favorite Internet browser, the web site contains
the following information:
• Product Support – Data sheets and errata, application notes and sample
programs, design resources, user’s guides and hardware support documents,
latest software releases and archived software
• General Technical Support – Frequently Asked Questions (FAQs), technical
support requests, online discussion groups, Microchip consultant program
member listing
• Business of Microchip – Product selector and ordering guides, latest Microchip
press releases, listing of seminars and events, listings of Microchip sales offices,
distributors and factory representatives
2012 Microchip Technology Inc.DS52071B-page 15
MPLAB® XC16 C Compiler User’s Guide
MICROCHIP FORUMS
Microchip provides additional online support via our web forums at
http://www.microchip.com/forums. Currently available forums are:
• Development Tools
•8-bit PIC MCUs
• 16-bit PIC MCUs
• 32-bit PIC MCUs
CUSTOMER SUPPORT
Users of Microchip products can receive assistance through several channels:
• Distributor or Representative
• Local Sales Office
• Field Application Engineer (FAE)
• Technical Support
Customers should contact their distributor, representative or field application engineer
(FAE) for support. Local sales offices are also available to help customers. A listing of
sales offices and locations is included in the back of this document. See our web site
for a complete, up-to-date listing of sales offices.
Technical support is available through the web site at http://support.microchip.com.
Documentation errors or comments may be emailed to docerrors@microchip.com.
DOCUMENT REVISION HISTORY
Revision A (April 2012)
Initial release of this document.
Revision B (July 2012)
• Chapter 2. “Common C Interface” was added.
• Figure 3-1 "Software Development Tools Data Flow" was updated.
• Table 3-16 "Linking Options" now includes the -fill option.
• Added the -pack_upper_byte qualifier information in
Section 6.10.4 “__pack_upper_byte Type Qualifier” and
Section 7.8 “Packing Data Stored in Flash”.
• Added DBRPAG/PSVP AG preservation bullet under Section 10.8 “Funct ion C all
Conventions”
• Fixed code syntax in Section 11.4 “Specifying the Interrupt Vector”.
• Fixed Eval Edition descri pti on unde r Chapter 15. “Optimizations”.
• Added "volatile" to SFR registers in Appendix F . “Built-in Functions”.
• Added built-in functions __builtin_write_CRYOTP and
__builtin_write_NVM_secure in Appendix F. “Built-in Functions”.
DS52071B-page 16 2012 Microchip Technology Inc.
Chapter 1. Compiler Overview
1.1INTRODUCTION
The MPLAB XC16 C compiler is defined and described in the following topics:
• Device Description
• Compiler Description and Documentation
• Compiler and Other Development Tools
1.2DEVICE DESCRIPTION
The MPLAB XC16 C compiler fully supports all Microchip 16-bit devices:
®
• The dsPIC
required in digital signal processor (DSP) applications with standard microcontroller (MCU) features need ed for embedded app li cat ion s.
• The PIC24 family of MCUs are identical to the dsPIC DSCs with the exception that
they do not have the digital signal controller module or that subset of instructions.
They are a subset, and are high-performance MCUs intended for applications that
do not require the power of the DSC capabilities.
family of digital signal controllers combines the high performance
MPLAB® XC16 C COMPILER
USER’S GUIDE
1.3COMPILER DESCRIPTION AND DOCUMENTATION
The MPLAB XC16 C compiler is a full-featured, optimizing compiler that translates
standard ANSI C programs into 16-bit device assembly language source. The compiler
also supports many command-line options and language extensions that allow full
access to the 16-bit device hardware capabilities, and affords fine control of the compiler code generator.
The compiler is a port of the GNU Compiler Collection (GCC) compiler from the Free
Software Foundation
This key features of the compiler are discussed in the following sections.
1.3.1ANSI C Standard
The compiler is a fully validated compiler that conforms to the ANSI C standard as
defined by the ANSI specification (ANSI x3.159-1989) and described in Kernighan and
Ritchie’s The C Programming Language (second edition). The ANSI standard includes
extensions to the original C definition that are now standard features of the language.
These extensions enhance portability and offer increased capability. In addition,
language extensions for dsPIC DSC embedded-control applications are included.
1.3.2Optimization
The compiler uses a set of sophisticated optimization passes that employ many
advanced techniques for generating efficient, compact code from C source. The
optimization passes include high-level optimizations that are applicable to any C code,
as well as 16-bit device-speci fic op timi zat ion s that take adva ntag e of the particular
features of the device architecture.
For more on optimizations, see Chapter 15. “Optimizations”.
2012 Microchip Technology Inc.DS52071B-page 17
MPLAB® XC16 C Compiler User’s Guide
1.3.3ANSI Standard Library Support
The compiler is distributed with a complete ANSI C standard library. All library functions
have been validated, and conform to the ANSI C library standard. The library includes
functions for string manipulation, dynamic memory allocation, data conversion, timekeeping and math functions (trigonometric, exponential and hyperbolic). The standard
I/O functions for file handling are also included, and, as distributed, they support full
access to the host file system using the command-line simulator. The fully functional
source code for the low-level file I/O functions is provided in the compiler distribution,
and may be used as a starting point for applications that require this capability.
1.3.4Flexible Memory Models
The compiler supports both large and small code and data models. The small code
model takes advantage of more efficient forms of call and branch instructions, while the
small data model supports the use of compact instructions for accessing data in SFR
space.
The compiler supports two models for accessing constant data. The “constants in data”
model uses d ata memory, which is initiali ze d b y t h e ru n -t ime li brary. The “constants in
code” model uses program memory, which is accessed through the Program Space
Visibility (PSV) window.
1.3.5Attributes and Qualifiers
The compiler keyword __attribute__ allows you to specify special attributes of
variables, structure fields or functions. This keyword is followed by an attribute
specification inside double parentheses, as in:
int last_mode __attribute__ ((persistent));
In other compilers, qualifiers are used to create qualified types:
persistent int last_mode;
The MPLAB XC16 C Compiler does have some non-standard qualifiers described in
Section 6.10 “Compiler-Specific type Qualifiers”.
Generally speaking, qualifiers indicate how an object should be accessed, whereas
attributes indicate where objects are to be located. Attributes also have many other
purposes.
1.3.6Compiler Driver
The compiler includes a powerful command-line driver program. Using the driver
program, application programs can be compiled, assembled and linked in a single step.
1.3.7Documentation
The compiler is supported under both the MPLAB IDE v8.xx and above, and the
MPLAB X IDE. For simplicity, both IDEs are referred to throughout the book as simply
MPLAB IDE.
Features that are unique to specific devices, and therefore specific compilers, are
noted with a “DD” icon next to the section and text that identifies the specific devices to
which the information applies (see the Preface).
DS52071B-page 18 2012 Microchip Technology Inc.
1.4COMPILER AND OTHER DEVELOPMENT TOOLS
The compiler works with many other Microchip tools including:
• MPLAB XC16 Assembler and Linker - see the MPLAB Assembler, Linker and Util-ities for PIC24 MCUs and dsPIC DSCs User’s Guide (DS51317).
• MPLAB IDE v8.xx and MPLAB X IDE
• The MPLAB SIM Simulator and MPLAB X Simulator
• All Microchip debug tools and programmers
• Demonstration boards and Starter kits that support 16-bit devices
Compiler Overview
2012 Microchip Technology Inc.DS52071B-page 19
MPLAB® XC16 C Compiler User’s Guide
NOTES:
DS52071B-page 20 2012 Microchip Technology Inc.
Chapter 2. Common C Interface
2.1INTRODUCTION
The Common C Interface (CCI) is available with all MPLAB XC C compilers and is
designed to enhance code portability between these compilers. For example,
CCI-conforming code would make it easier to port from a PIC18 MCU using the MPLAB
XC8 C compiler to a PIC24 MCU using the MPLAB XC16 C compiler.
The CCI assumes that your source code already conforms to the ANSI Standard. If you
intend to use the CCI, it is your responsibility to write code that conforms. Legacy projects will need to be migrated to achieve conformance. A compiler option must also be
set to ensure that the operation of the compiler is consistent with the interface when the
project is built.
The following topics are examined in this chapter of the MPLAB XC16 C Compiler
User’s Guide:
• ANSI Standard Extensions
• Using the CCI
• ANSI Standard Refinement
• ANSI Standard Extensions
MPLAB® XC16 C COMPILER
USER’S GUIDE
2.2BACKGROUND – THE DESIRE FOR PORTABLE CODE
All programmers want to write portable source code.
Portability means that the same source code can be compiled and run in a different
execution environment than that for which it was written. Rarely can code be one hundred percent portable, but the more tolerant it is to change, the less time and effort it
takes to have it running in a new environment.
Embedded engineers typically think of code portability as being across target devices,
but this is only part of the situation. The same code could be compiled for the same
target but with a different compiler. Differences between those compilers might lead to
the code failing at compile time or runtime, so this must be considered as well.
Y ou may only write code for one target device and only use one brand of compiler, but
if there is no regulation of the compiler’s operation, simply updating your compiler
version may change your code’s behavior.
Code must be portable across targets, tools, and time to be truly flexible.
Clearly, this portability cannot be achieved by the programmer alone, since the com-
piler vendors can base their products on different technologies, implement different features and code syntax, or improve the way their product works. Many a great compiler
optimization has broken many an unsuspecting project.
Standards for the C language have been developed to ensure that change is managed
and code is more portable. The American National Standards Institute (ANSI) publishes standards for many disciplines, including programming languages. The ANSI C
Standard is a universally adopted standard for the C programming language.
2012 Microchip Technology Inc.DS52071B-page 21
MPLAB® XC16 C Compiler User’s Guide
2.2.1The ANSI Standard
The ANSI C Standard has to reconcile two opposing goals: freedom for compilers vendors to target new devices and improve code generation, with the known functional
operation of source code for programmers. If both goals can be met, source code can
be made portable.
The standard is implemented as a set of rules which detail not only the syntax that a
conforming C program must follow, but the semantic rules by which that program will
be interpreted. Thus, for a compiler to conform to the standard, it must ensure that a
conforming C program functions as described by the standard.
The standard describes implementation, the set of tools and the runtime environment
on which the code will run. If any of these change, e.g., you build for, and run on, a different target device, or if you update the version of the compiler you use to build, then
you are using a different implementation.
The standard uses the term behavior to mean the external appearance or action of the
program. It has nothing to do with how a program is encoded.
Since the standard is trying to achieve goals that could be construed as conflicting,
some specifications appear somewhat vague. For example, the standard states that an
int type must be able to hold at least a 16-bit value, but it does not go as far as saying
what the size of an int actually is; and the action of right-shifting a signed integer can
produce different results on different implementations; yet, these different results are
still ANSI C compliant.
If the standard is too strict, device architectures may not allow the compiler to conform.
But, if it is too weak, programmers would see wildly differing results within different
compilers and architectures, and the standard would loose its effectiveness.
The standard organizes source code whose behavior is not fully defined into groups
that include the following behaviors:
Implementation-defined behavior
This is unspecified behavior where each implementation documents how the choice
is made.
Unspecified behavior
The standard provides two or more possibilities and imposes no further requirements
on which possibility is chos en in any part ic ula r ins ta nc e.
Undefined behavior
This is behavior for which the standard imposes no requirements.
1
Code that strictly conforms to the standard does not produce output that is dependent
on any unspecified, undefined, or implementation-defined behavior. The size of an
int, which we used as an example earlier, falls into the category of behavior that is
defined by implementation. That is to say, the size of an int is defined by which compiler is being used, how that compiler is being used, and the device that is being targeted.
All the MPLAB XC compilers conform to the ANS X3.159-1989 Standard for programming languages (with the exception of the XC8 compiler’s inability to allow recursion,
as mentioned in the footnote). This is commonly called the C89 Standard. Some features from the later standard, C99, are also supported.
1. Case in point: The mid-range PIC® microcontrollers do not have a data stack. Because a compiler
targeting this device cannot implement recursion, it (strictly speaking) cannot conform to the ANSI
C Standard. This example illustrate a situation in which the standard is too strict for mid-range
devices and tools.
DS52071B-page 22 2012 Microchip Technology Inc.
Common C Interface
For freestanding implementations – or for what we typically call embedded applications
– the standard allows non-standard extensions to the language, but obviously does not
enforce how they are specified or how they work. When working so closely to the
device hardware, a programmer needs a means of specifying device setup and interrupts, as well as utilizing the often complex world of small-device memory
architectures. This cannot be offered by the standard in a consistent way.
While the ANSI C Standard provides a mutual understanding for programmers and
compiler vendors, programmers need to consider the implementation-defined behavior
of their tools and the probability that they may need to use extensions to the C language
that are non-standard. Both of these circumstances can have an impact on code portability.
2.2.2The Common C Interface
The Common C Interface (CCI) supplements the ANSI C Standard and makes it easier
for programmers to achieve consistent outcomes on all Microchip devices when using
any of the MPLAB XC C compilers.
It delivers the following improvements, all designed with portability in mind.
Refinement of the ANSI C Standard
The CCI documents specific behavior for some code in which actions are implemen-
tation-defined behavior under the ANSI C Standard. For example, the result of
right-shifting a signed integer is fully defined by the CCI. Note that many
implementation-defined items that closely couple with device characteristics, such as
the size of an int, are not defined by the CCI.
Consistent syntax for non-standard extensions
The CCI non-standard extensions are mostly implemented using keywords with a uni-
form syntax. They replace keywords, macros and attributes that are the native compiler implementation. The interpretation of the keyword may differ across each compiler, and any arguments to the keywords may be device specific.
Coding guidelines
The CCI may indicate advice on how code should be written so that it can be ported
to other devices or compilers. While you may choose not to follow the advice, it will
not conform to the CCI.
2012 Microchip Technology Inc.DS52071B-page 23
MPLAB® XC16 C Compiler User’s Guide
2.3USING THE CCI
The CCI allows enhanced portability by refining implementation-defined behavior and
standardizing the syntax for extensions to the language.
The CCI is something you choose to follow and put into effect, thus it is relevant for new
projects, although you may choose to modify existing projects so they conform.
For your project to conform to the CCI, you must do the following things.
Enable the CCI
Select the MPLAB IDE widget Use CCI Syntax
command-line option that is equivalent.
Include <xc.h> in every module
Some CCI features are only enabled if this header is seen by the compiler.
Ensure ANSI compliance
Code that does not conform to the ANSI C Standard does not confirm to the CCI.
Observe refinements to ANSI by the CCI
Some ANSI implementation-defined behavior is defined explicitly by the CCI.
Use the CCI extensions to the language
Use the CCI extensions rather than the native language extensions
in your project, or use the
The next sections detail specific items associated with the CCI. These items are segregated into those that refine the standard, those that deal with the ANSI C Standard
extensions, and other miscellaneous compiler options and usage. Guidelines are indicated with these item s.
If any implementation-defined behavior or any non-standard extension is not discussed
in this document, then it is not part of the CCI. For example, GCC case ranges, label
addresses and 24-bit short long types are not part of the CCI. Programs which use
these features do not conform to the CCI. The compiler may issue a warning or error
to indicate when you use a non-CCI feature and the CCI is enabled.
DS52071B-page 24 2012 Microchip Technology Inc.
2.4ANSI STANDARD REFINEMENT
The following topics describe how the CCI refines the implementation-defined
behaviors outlined in the ANSI C Standard.
2.4.1Source File Encoding
Under the CCI, a source file must be written using characters from the 7-bit ASCII set.
Lines may be terminated using a line feed ('\n') or carriage return ('\r') that is immediately followed by a line feed. Escaped characters may be used in character constants
or string literals to represent extended characters not in the basic character set.
2.4.1.1EXAMPLE
The following shows a string constant being defined that uses escaped characters.
const char myName[] = "Bj\370rk\n";
2.4.1.2DIFFERENCES
All compilers have used this character set.
2.4.1.3MIGRATION TO THE CCI
No action required.
Common C Interface
2.4.2The Prototype for main
The prototype for the main() function is
int main(void);
2.4.2.1EXAMPLE
The following shows an example of how main() might be defined
int main(void)
{
while(1)
process();
}
2.4.2.2DIFFERENCES
The 8-bit compilers used a void return type for this function.
2.4.2.3MIGRATION TO THE CCI
Each program has one definition for the main() function. Confirm the return type for main() in all projects previously compiled for 8-bit targets.
2.4.3Header File Specification
Header file specifications that use directory separators do not conform to the CCI.
2.4.3.1EXAMPLE
The following example shows two confor mi ng incl ude dir ect ive s.
#include <usb_main.h>
#include "global.h"
2012 Microchip Technology Inc.DS52071B-page 25
MPLAB® XC16 C Compiler User’s Guide
2.4.3.2DIFFERENCES
Header file specifications that use directory separators have been allowed in previous
versions of all compilers. Compatibility problems arose when Windows-style separators “\” were used and the code compiled under other host operating systems. Under
the CCI, no directory specifiers should be used.
2.4.3.3MIGRATION TO THE CCI
Any #include directiv es that use di rectory sep arators in the header fil e specifica tions
should be changed. Remove all but the header file name in the directive. Add the directory path to the compiler’s include search path or MPLAB IDE equivalent. This will force
the compiler to search the directories specified with this option.
For example, the following code:
#include <inc/lcd.h>
should be changed to:
#include <lcd.h>
and the path to the inc directory added to the compiler’s header search path in your
MPLAB IDE project properties, or on the command-line as follows:
-Ilcd
2.4.4Include Search Paths
When you include a header file under the CCI, the file should be discoverable in the
paths searched by the compiler detailed below.
For any header files specified in angle bracket delimiters < >, the search paths should
be those specified by -I options (or the equivalent MPLAB IDE option), then the standard compiler include directories. The -I options are searched in the order in which
they are specified.
For any file specified in quote characters " ", the search paths should first be the current working directory . In the case of an MPLAB X project, the current working directory
is the directory in which the C source file is located. If unsuccessful, the search paths
should be the same directories searched when the header files is specified in angle
bracket delimiters.
Any other options to specify search paths for header files do not conform to the CCI.
2.4.4.1EXAMPLE
If including a header file as in the following directive
#include "myGlobals.h"
The header file should be locatable in the current working directory, or the paths specified by any -I options, or the standard compiler directories. If it is located elsewhere,
this does not conform to the CCI.
2.4.4.2DIFFERENCES
The compiler operation under the CCI is not changed. This is purely a coding guide line.
2.4.4.3MIGRATION TO THE CCI
Remove any option that specifies header file search paths other than the -I option (or
the equivalent MPLAB IDE option), and use the -I option in place of this. Ensure the
header file can be found in the directories specified in this section.
DS52071B-page 26 2012 Microchip Technology Inc.
Common C Interface
2.4.5The number of Significant Initial Characters in an Identi fier
At least the first 255 characters in an identifier (internal and external) are significant.
This extends upon the requirement of the ANSI C Standard which states a lower number of significant characters are used to identify an object.
2.4.5.1EXAMPLE
The following example shows two poorly named variables, but names which are
considered unique under the CCI.
int stateOfPortBWhenTheOperatorHasSelectedAutomaticModeAndMotorIsRunningFast;
int stateOfPortBWhenTheOperatorHasSelectedAutomaticModeAndMotorIsRunningSlow;
2.4.5.2DIFFERENCES
Former 8-bit compilers used 31 significant characters by default, but an option allowed
this to be extended.
The 16- and 32-bit compilers did not impose a limit on the number of significant characters.
2.4.5.3MIGRATION TO THE CCI
No action required. You may take advantage of the less restrictive naming scheme.
2.4.6Sizes of Types
The sizes of the basic C types, for example char, int and long, are not fully defined
by the CCI. These types, by design, reflect the size of registers and other architectural
features in the target device. They allow the device to efficiently access objects of this
type. The ANSI C Standard does, however, indicate minimum requirements for these
types, as specified in <limits.h>.
If you need fixed-size types in your project, use the types defined in <stdint.h>, e.g.,
uint8_t or int16_t. These types are consistently defined across all XC compilers,
even outside of the CCI.
Essentially, the C language offers a choice of two groups of types: those that offer sizes
and formats that are tailored to the device you are using; or those that have a fixed size,
regardless of the target.
2.4.6.1EXAMPLE
The following example shows the definition of a variable, native, whose size will allow
efficient access on the target device; and a variable, fixed, whose size is cle a rl y i n di cated and remains fixed, even though it may not allow efficient access on every device.
int native;
int16_t fixed;
2.4.6.2DIFFERENCES
This is consistent with previous types implemented by the compiler.
2.4.6.3MIGRATION TO THE CCI
If you require a C type that has a fixed size, regardless of the target device, use one of
the types defined by <stdint.h>.
2012 Microchip Technology Inc.DS52071B-page 27
MPLAB® XC16 C Compiler User’s Guide
2.4.7Plain char Types
The type of a plain char is unsigned char. It is generally recommended that all definitions for the char type explicitly state the signedness of the object.
2.4.7.1EXAMPLE
The following example
char foobar;
defines an unsigned char object called foobar.
2.4.7.2DIFFERENCES
The 8-bit compilers have always treated plain char as an unsigned type.
The 16- and 32-bit compilers used signed char as the default plain char type. The
-funsigned-char option on those compilers changed the default type to be
unsigned char.
2.4.7.3MIGRATION TO THE CCI
Any definition of an object defined as a plain char and using the 16- or 32-bit compilers
needs review. Any plain char that was intended to be a signed quantity should be
replaced with an explicit definition, for example.
signed char foobar;
You may use the -funsigned-char option on XC16/32 to change the type of plain
char, but since this option is not supported on XC8, the code is not strictly conforming.
2.4.8Signed Integer Representation
The value of a signed integer is determined by taking the two’s complement of the integer.
2.4.8.1EXAMPLE
The following shows a variable, test, that is assigned the value -28 decimal.
signed char test = 0xE4;
2.4.8.2DIFFERENCES
All compilers have represented signed integers in the way described in this section.
2.4.8.3MIGRATION TO THE CCI
No action required.
DS52071B-page 28 2012 Microchip Technology Inc.
Common C Interface
2.4.9Integer conversion
When converting an integer type to a signed integer of insufficient size, the original
value is truncated from the most-significant bit to accommodate the target size.
2.4.9.1EXAMPLE
The following shows an assignment of a value that will be truncated.
signed char destination;
unsigned int source = 0x12FE;
destination = source;
Under the CCI, the value of destination after the alignment will be -2 (i.e., the bit
pattern 0xFE).
2.4.9.2DIFFERENCES
All compilers have performed integer conversion in an identical fashion to that
described in this section.
2.4.9.3MIGRATION TO THE CCI
No action required.
2.4.10Bit-wise Operations on Signed Values
Bitwise operations on signed values act on the two’s complement representation,
including the sign bit. See also Section 2.4.11 “Right-shifting Signed Values”.
2.4.10.1EXAMPLE
The following shows an example of a negative quantity involved in a bitwise AND operation.
Under the CCI, the value of output after the assignment will be -2 (i.e., the bit pattern
0xFE).
2012 Microchip Technology Inc.DS52071B-page 29
MPLAB® XC16 C Compiler User’s Guide
2.4.11.2DIFFERENCES
All compilers have performed right shifting as described in this section.
2.4.11.3MIGRATION TO THE CCI
No action required.
2.4.12Conversion of Union Member Accessed Using Member With
Different Type
If a union defines several members of different types and you use one member identifier to try to access the contents of another (whether any conversion is applied to the
result) is implementation-defined behavior in the standard. In the CCI, no conversion is
applied and the bytes of the union object are interpreted as an object of the type of the
member being accessed, without regard for alignment or other possible invalid conditions.
2.4.12.1EXAMPLE
The following shows an example of a union defining several members.
union {
signed char code;
unsigned int data;
float offset;
} foobar;
Code that attempts to extract offset by reading data is not guaranteed to read the
correct value.
float result;
result = foobbar.data;
2.4.12.2DIFFERENCES
All compilers have not converted union members accessed via other members.
2.4.12.3MIGRATION TO THE CCI
No action required.
2.4.13Default Bit-field int Type
The type of a bit-field specified as a plain int will be identical to that of one defined
using unsigned int. This is quite different to other objects where the types int,
signed and signed int are synonymous. It is recommended that the signedness of
the bit-field be explicitly stated in all bit-field definitions.
2.4.13.1EXAMPLE
The following shows an example of a structure tag containing bit-fields which are
unsigned integers and with the size specified.
struct OUTPUTS {
int direction :1;
int parity :3;
int value :4;
};
DS52071B-page 30 2012 Microchip Technology Inc.
Common C Interface
2.4.13.2DIFFERENCES
The 8-bit compilers have previously issued a warning if type int was used for bit-fields,
but would implement the bit-field with an unsigned int type.
The 16- and 32-bit compilers have implemented bit-fields defined using int as having
a signed int type, unless the option -funsigned-bitfields was specified.
2.4.13.3MIGRATION TO THE CCI
Any code that defines a bit-field with the plain int type should be reviewed. If the inten-
tion was for these to be signed quantities, then the type of these should be changed to
signed int, for example, in:
struct WAYPT {
int log :3;
int direction :4;
};
the bit-field type should be changed to signed int, as in:
struct WAYPT {
signed int log :3;
signed int direction :4;
};
2.4.14Bit-fields Straddling a Storage Unit Boundary
Whether a bit-field can straddle a storage unit boundary is implementation-defined
behavior in the standard. In the CCI, bit-fields will not straddle a storage unit boundary;
a new storage unit will be allocated to the structure, and padding bits will fill the gap.
Note that the size of a storage unit differs with each compiler as this is based on the
size of the base data type (e.g., int) from which the bit-field type is derived. On 8-bit
compilers this unit is 8-bits in size; for 16-bit compilers, it is 16 bits; and for 32-bit compilers, it is 32 bits in size.
2.4.14.1EXAMPLE
The following shows a structure containing bit-fields being defined.
struct {
unsigned first : 6;
unsigned second :6;
} order;
Under the CCI and using XC8, the storage allocation unit is byte sized. The bit-field
second, will be allocated a new storage unit since there are only 2 bits remaining in
the first storage unit in which first is allocated. The size of this structure, order, will
be 2 bytes.
2.4.14.2DIFFERENCES
This allocation is identical with that used by all previous compilers.
2.4.14.3MIGRATION TO THE CCI
No action required.
2.4.15The Allocation Order of Bits-field
The memory ordering of bit-fields into their storage unit is not specified by the ANSI C
Standard. In the CCI, the first bit defined will be the least significant bit of the storage
unit in which it will be allocated.
2012 Microchip Technology Inc.DS52071B-page 31
MPLAB® XC16 C Compiler User’s Guide
2.4.15.1EXAMPLE
The following shows a structure containing bit-fields being defined.
struct {
unsigned lo : 1;
unsigned mid :6;
unsigned hi : 1;
} foo;
The bit-field lo will be assigned the least significant bit of the storage unit assigned to
the structure foo. The bit-field mid will be assigned the next 6 least significant bits, and
hi, the most significant bit of that same storage unit byte.
2.4.15.2DIFFERENCES
This is identical with the previous operation of all compilers.
2.4.15.3MIGRATION TO THE CCI
No action required.
2.4.16The NULL macro
The NULL macro is defined in <stddef.h>; however, its definition is implementation-defined behavior. Under the CCI, the definition of NULL is the expression (0).
2.4.16.1EXAMPLE
The following shows a pointer being assigned a null pointer constant via the NULL
macro.
int * ip = NULL;
The value of NULL, (0), is implicitly cast to the destination type.
2.4.16.2DIFFERENCES
The 32-bit compilers previously assigned NULL the expression ((void *)0).
2.4.16.3MIGRATION TO THE CCI
No action required.
2.4.17Floating-point sizes
Under the CCI, floating-point types must not be smaller than 32 bits in size.
2.4.17.1EXAMPLE
The following shows the definition for outY, which will be at least 32-bit in size.
float outY;
2.4.17.2DIFFERENCES
The 8-bit compilers have allowed the use of 24-bit float and double types.
2.4.17.3MIGRATION TO THE CCI
When using 8-bit compilers, the float and double type will automatically be made
32 bits in size once the CCI mode is enabled. Review any source code that may have
assumed a float or double type and may have been 24 bits in size.
No migration is required for other compilers.
DS52071B-page 32 2012 Microchip Technology Inc.
2.5ANSI STANDARD EXTENSIONS
The following topics describe how the CCI provides device-specific extensions to the
standard.
2.5.1Generic Header File
A single header file <xc.h> must be used to declare all compiler- and device-specific
types and SFRs. You must include this file into every module to conform with the CCI.
Some CCI definitions depend on this header being seen.
2.5.1.1EXAMPLE
The following shows this header file being included, thus allowing conformance with the
CCI, as well as allowing access to SFRs.
#include <xc.h>
2.5.1.2DIFFERENCES
Some 8-bit compilers used <htc.h> as the equivalent header. Previous versions of
the 16- and 32-bit compilers used a variety of headers to do the same job.
2.5.1.3MIGRATION TO THE CCI
Change:
#include <htc.h>
used previously in 8-bit compiler code, or family-specific header files as in the following
examples:
Variables and functions can be placed at an absolute address by using the __at()
construct.qualifier Note that XC16/32 may require the variable or function to be placed
in a special section for absolute addressing to work. Stack-based (auto and parameter) varia bles cannot use the __at() specifier.
2.5.2.1EXAMPLE
The following shows two variables and a function being made absolute.
2.5.2.2DIFFERENCES
The 8-bit compilers have used an @ symbol to specify an absolute address.
The 16- and 32-bit compilers have used the address attribute to specify an object’s
address.
2012 Microchip Technology Inc.DS52071B-page 33
MPLAB® XC16 C Compiler User’s Guide
2.5.2.3MIGRATION TO THE CCI
Avoid making objects and functions absolute if possible.
In XC8, change absolute object definitions such as the following example:
int scanMode @ 0x200;
to:
int scanMode __at(0x200);
In XC16/32, change code such as:
int scanMode __attribute__(address(0x200)));
to:
int scanMode __at(0x200);
2.5.2.4CAVEATS
If the __at() and __section() specifiers are both applied to an object when using
XC8, the __section() specifier is currently ignored.
2.5.3Far Objects and Functions
The __far qualifier may be used to indicate that variables or functions may be located
in ‘far memory’. Exactly what constitutes far memory is dependent on the target device,
but it is typically memory that requires more complex code to access. Expressions
involving far-qualified objects may generate slower and larger code.
Use the native keywords discussed in the Differences section to look up information on
the semantics of this qualifier.
Some devices may not have such memory implemented, in which case, use of this
qualifier will be ignored. Stack-based (auto and parameter) variables cannot use the
__far specifier.
2.5.3.1EXAMPLE
The following shows a variable and function qualified using __far.
__far int serialNo;
__far int ext_getCond(int selector);
2.5.3.2DIFFERENCES
The 8-bit compilers have used the qualifier far to indicate this meaning. Functions
could not be qualified as far.
The 16-bit compilers have used the far attribute with both variables and functions.
The 32-bit compilers have used the far attribute with functions, only.
DS52071B-page 34 2012 Microchip Technology Inc.
Common C Interface
2.5.3.3MIGRATION TO THE CCI
For 8-bit compilers, change any occurrence of the far qualifier, as in the following
example:
far char template[20];
to __far, i.e., __far char template[20];
In the 16- and 32-bit compilers, change any occurrence of the far attribute, as in the
following
void bar(void) __attribute__ ((far));
int tblIdx __attribute__ ((far));
to
void __far bar(void);
int __far tblIdx;
2.5.3.4CAVEATS
None.
2.5.4Near Objects
The __near qualifier may be used to indicate that variables or functions may be
located in ‘near memory’. Exactly what constitutes near memory is dependent on the
target device, but it is typically memory that can be accessed with less complex code.
Expressions involving near-qualified objects may be faster and result in smaller code.
Use the native keywords discussed in the Differences section to look up information on
the semantics of this qualifier.
Some devices may not have such memory implemented, in which case, use of this
qualifier will be ignored. Stack-based (auto and parameter) variables cannot use the
__near specifier.
2.5.4.1EXAMPLE
The following shows a variable and function qualified using __near.
__near int serialNo;
__near int ext_getCond(int selector);
2.5.4.2DIFFERENCES
The 8-bit compilers have used the qualifier near to indicate this meaning. Functions
could not be qualified as near.
The 16-bit compilers have used the near attribute with both variables and functions.
The 32-bit compilers have used the near attribute for functions, only.
2012 Microchip Technology Inc.DS52071B-page 35
MPLAB® XC16 C Compiler User’s Guide
2.5.4.3MIGRATION TO THE CCI
For 8-bit compilers, change any occurrence of the near qualifier, as in the following
example:
near char template[20];
to __near, i.e., __near char template[20];
In 16- and 32-bit compilers, change any occurrence of the near attribute, as in the fol-
lowing
void bar(void) __attribute__ ((near));
int tblIdx __attribute__ ((near));
to
void __near bar(void);
int __near tblIdx;
2.5.4.4CAVEATS
None.
2.5.5Persistent Objects
The __persistent qualifier may be used to indicate that variables should not be
cleared by the runtime startup code.
Use the native keywords discussed in the Differences section to look up information on
the semantics of this qualifier.
2.5.5.1EXAMPLE
The following shows a variable qualified using __persistent.
__persistent int serialNo;
2.5.5.2DIFFERENCES
The 8-bit compilers have used the qualifier, persistent, to indicate this meaning.
The 16- and 32-bit compilers have used the persistent attribute with variables to
indicate they were not to be cleared.
2.5.5.3MIGRATION TO THE CCI
With 8-bit compilers, change any occurrence of the persistent qualifier, as in the following example:
persistent
char template[20];
to __persistent, i.e., __persistentchar template[20];
For the 16- and 32-bit compilers, change any occurrence of the persistent attribute,
as in the following
int tblIdx __attribute__ ((persistent));
to
int __persistent tblIdx;
2.5.5.4CAVEATS
None.
DS52071B-page 36 2012 Microchip Technology Inc.
Common C Interface
2.5.6X and Y Data Objects
The __xdata and __ydata qualifiers may be used to indicate that variables may be
located in special memory regions. Exactly what constitutes X and Y memory is dependent on the target device, but it is typically memory that can be accessed independently
on separate buses. Such memory is often required for some DSP instructions.
Use the native keywords discussed in the Differences section to look up information on
the semantics of these qualifiers.
Some devices may not have such memory implemented; in which case, use of these
qualifiers will be ignored.
2.5.6.1EXAMPLE
The following shows a variable qualified using __xdata, as well as another variable
qualified with __ydata.
__xdata char data[16];
__ydata char coeffs[4];
2.5.6.2DIFFERENCES
The 16-bit compilers have used the xmemory and ymemory space attribute with
variables.
Equivalent specifiers have never been defined for any other compiler.
2.5.6.3MIGRATION TO THE CCI
For 16-bit compilers, change any occurrence of the space attributes xmemory or
ymemory, as in the following example:
char __attribute__((space(xmemory)))template[20];
to __xdata, or __ydata, i.e., __xdata char template[20];
2.5.6.4CAVEATS
None.
2.5.7Banked Data Objects
The __bank(num) qualifier may be used to indicate that variables may be located in
a particular data memory bank. The number, num, represents the bank number. Exactly
what constitutes banked memory is dependent on the target device, but it is typically a
subdivision of data memory to allow for assembly instructions with a limited address
width field.
Use the native keywords discussed in the Differences section to look up information on
the semantics of these qualifiers.
Some devices may not have banked data memory implemented, in which case, use of
this qualifier will be ignored. The number of data banks implemented will vary from one
device to another.
2.5.7.1EXAMPLE
The following shows a variable qualified using __bank().
__bank(0) char start;
__bank(5) char stop;
2012 Microchip Technology Inc.DS52071B-page 37
MPLAB® XC16 C Compiler User’s Guide
2.5.7.2DIFFERENCES
The 8-bit co mpile rs hav e used the fo ur qua lifie rs bank0, bank1, bank2 and bank3 to
indicate the same, albeit more limited, memory placement.
Equivalent specifiers have never been defined for any other compiler.
2.5.7.3MIGRATION TO THE CCI
For 8-bit compilers, change any occurrence of the bankx qualifiers, as in the following
example:
bank2 int logEntry;
to __bank(, i.e., __bank(2) int logEntry;
2.5.7.4CAVEATS
None.
2.5.8Alignment of Objects
The __align(alignment) specifier may be used to indicate that variables must be
aligned on a memory address that is a multiple of the alignment specified. The alignment term must be a power of two. Positive values request that the object’s start
address be aligned; negative values imply the object’s end address be aligned.
Use the native keywords discussed in the Differences section to look up information on
the semantics of this specifier.
2.5.8.1EXAMPLE
The following shows variables qualified using __align() to ensure they end on an
address that is a multiple of 8, and start on an address that is a multiple of 2,
respectively.
__align(-8) int spacer;
__align(2) char coeffs[6];
2.5.8.2DIFFERENCES
An alignment feature has never been implemented on 8-bit compilers.
The 16- and 32-bit compilers used the aligned attribute with variables.
2.5.8.3MIGRATION TO THE CCI
For 16- and 32-bit compilers, change any occurrence of the aligned attribute, as in
the following example:
char __attribute__((aligned(4)))mode;
to __align, i.e., __align(4) char mode;
2.5.8.4CAVEATS
This feature is not yet implemented on XC8.
DS52071B-page 38 2012 Microchip Technology Inc.
Common C Interface
2.5.9EEPROM Objects
The __eeprom qualif ier may be us ed to indi cate that variable s should be positio ned in
EEPROM.
Use the native keywords discussed in the Differences section to look up information on
the semantics of this qualifier.
Some devices may not implement EEPROM. Use of this qualifier for such devices will
generate a warning. Stack-based (auto and parameter) variables cannot use the
__eeprom specifier.
2.5.9.1EXAMPLE
The following shows a variable qualified using __eeprom.
__eeprom int serialNos[4];
2.5.9.2DIFFERENCES
The 8-bit compilers have used the qualifier, eeprom, to indicate this meaning for some
devices.
The 16-bit compilers have used the space attribute to allocate variables to the memory
space used for EEPROM.
2.5.9.3MIGRATION TO THE CCI
For 8-bit compilers, change any occurrence of the eeprom qualifier, as in the following
example:
eeprom
to __eeprom, i.e., __eeprom char title[20];
For 16-bit compilers, change any occurrence of the eedata space attribute, as in the
following
int mainSw __attribute__ ((space(eedata)));
to
int __eeprom mainSw;
2.5.9.4CAVEATS
XC8 does not implement the __eeprom qualifiers for any PIC18 devices; this qualifier
will work as expected for other 8-bit devices.
char title[20];
2.5.10Interrupt Functions
The __interrupt(type) specifier may be used to indicate that a function is to act
as an interrupt service routine. The type is a comma-separated list of keywords that
indicate information about the interrupt function.
The current interrupt types are:
<empty>
Implement the default interrupt function
low_priority
The interrupt function corresponds to the low priority interrupt source (XC8 – PIC18
only)
high_priority
The interrupt function corresponds to the high priority interrupt source (XC8)
2012 Microchip Technology Inc.DS52071B-page 39
MPLAB® XC16 C Compiler User’s Guide
save(symbol-list)
Save on entry and restore on exit the listed symbols (XC16)
irq(irqid)
Specify the interrupt vector associated with this interrupt (XC16)
altirq(altirqid)
Specify the alternate interrupt vector associated with this interrupt (XC16)
preprologue(asm)
Specify assembly code to be executed before any compiler-generated interrupt code
(XC16)
shadow
Allow the ISR to utilise the shadow registers for context switching (XC16)
auto_psv
The ISR will set the PSVPAG register and restore it on exit (XC16)
no_auto_psv
The ISR will not set the PSVPAG register (XC16)
Use the native keywords discussed in the Differences section to look up information on
the semantics of this specifier.
Some devices may not implement interrupts. Use of this qualifier for such devices will
generate a warning. If the argument to the __interrupt specifier does not make
sense for the target device, a warning or error will be issued by the compiler.
2.5.10.1EXAMPLE
The following shows a function qualified using __interrupt.
__interrupt(low_priority) void getData(void) {
if (TMR0IE && TMR0IF) {
TMR0IF=0;
++tick_count;
}
}
2.5.10.2DIFFERENCES
The 8-bit compilers have used the interrupt and low_priority qualifiers to indicate this meaning for some devices. Interrupt routines were by default high priority.
The 16- and 32-bit compilers have used the interrupt attribute to define interrupt
functions.
DS52071B-page 40 2012 Microchip Technology Inc.
Common C Interface
2.5.10.3MIGRATION TO THE CCI
For 8-bit compilers, change any occurrence of the interrupt qualifier, as in the
For 32-bit compilers, the __interrupt() keyword takes two parameters, the vector
number and the (optional) IPL value. Change code which uses the interrupt attribute, similar to these examples:
/* Determine IPL and context-saving mode at runtime */
void __attribute__((vector(2), interrupt(), nomips16))
myisr2_RUNTIME(void) {}
to
void __interrupt(0,IPL7AUTO) myisr0_7A(void) {}
void __interrupt(1,IPL6SRS) myisr1_6SRS(void) {}
/* Determine IPL and context-saving mode at runtime */
void __interrupt(2) myisr2_RUNTIME(void) {}
2.5.10.4CAVEATS
None.
2012 Microchip Technology Inc.DS52071B-page 41
MPLAB® XC16 C Compiler User’s Guide
2.5.11Packing Objects
The __pack specifier may b e us ed to i n di ca t e th at s tr uc t ur es sh ou ld n ot u se m emo r y
gaps to align structure members, or that individual structure members should not be
aligned.
Use the native keywords discussed in the Differences section to look up information on
the semantics of this specifier.
Some compilers may not pad structures with alignment gaps for some devices and use
of this specifier for such devices will be ignored.
2.5.11.1EXAMPLE
The following shows a structure qualified using __pack as well as a structure where
one member has been explicitly packed.
__pack struct DATAPOINT {
unsigned char type;
int value;
} x-point;
struct LINETYPE {
unsigned char type;
__pack int start;
long total;
} line;
2.5.11.2DIFFERENCES
The __pack specifier is a new CCI specifier available with XC8. This specifier has no
apparent effect since the device memory is byte addressable for all data objects.
The 16- and 32-bit compilers have used the packed attribute to indicate that a struc-
ture member was not aligned with a memory gap.
2.5.11.3MIGRATION TO THE CCI
No migration is required for XC8.
For 16- and 32-bit compilers, change any occurrence of the packed attribute, as in the
following example:
struct DOT
{
char a;
int x[2] __attribute__ ((packed));
};
to:
struct DOT
{
char a;
__pack int x[2];
};
Alternatively, you may pack the entire structure, if required.
2.5.11.4CAVEATS
None.
DS52071B-page 42 2012 Microchip Technology Inc.
Common C Interface
2.5.12Indicating Antiquated Objects
The __deprecate specifier may be used to indicate that an object has limited longev-
ity and should not be used in new designs. It is commonly used by the compiler vendor
to indicate that compiler extensions or features may become obsolete, or that better
features have been developed and which should be used in preference.
Use the native keywords discussed in the Differences section to look up information on
the semantics of this specifier.
2.5.12.1EXAMPLE
The following shows a function which uses the __deprecate keyword.
void __deprecate getValue(int mode)
{
//...
}
2.5.12.2DIFFERENCES
No deprecate feature was implemented on 8-bit compilers.
The 16- and 32-bit compilers have used the deprecated attribute (note different spell-
ing) to indicate that objects should be avoided if possible.
2.5.12.3MIGRATION TO THE CCI
For 16- and 32-bit compilers, change any occurrence of the deprecated attribute, as
in the following example:
int __attribute__(deprecated) intMask;
to:
int __deprecate intMask;
2.5.12.4CAVEATS
None.
2.5.13Assigning Objects to Sections
The __section() specifier may be used to indicate that an object should be located
in the named section (or psect, using the XC8 terminology). This is typically used when
the object has special and unique linking requirements which cannot be addressed by
existing compiler features.
Use the native keywords discussed in the Differences section to look up information on
the semantics of this specifier.
2.5.13.1EXAMPLE
The following shows a variable which uses the __section keyword.
int __section("comSec") commonFlag;
2012 Microchip Technology Inc.DS52071B-page 43
MPLAB® XC16 C Compiler User’s Guide
2.5.13.2DIFFERENCES
The 8-bit compilers have used the #pragma psect directive to redirect obje cts to a
new section, or psect. The operation of the __section() specifier is different to this
pragma in several ways, described below.
Unlike with the pragma, the new psect created with __section() does not inherit the
flags of the psect in which the object would normally have been allocated. This means
that the new psect can be linked in any memory area, including any data bank. The
compiler will also make no assumptions about the location of the object in the new section. Objects redirected to new psects using the pragma must always be linked in the
same memory area, albeit at any address in that area.
The __section() specifier allows objects that are initialized to be placed in a different
psect. Initialization of the object will still be performed even in the new psect. This will
require the automatic allocation of an additional psect (whose name will be the same
as the new psect prefixed with the letter i), which will contain the initial values. The
pragma cannot be used with objects that are initialized.
Objects allocated a different psect with __section() will be cleared by the runtime
startup code, unlike objects which use the pragma.
Y ou must reserve memory, and locate via a linker option, for any new psect created with
a __section() specifier in the current XC8 compiler implementation.
The 16- and 32-bit compilers have used the section attribute to indicate a different
destination section name. The __section() specifier works in a similar way to the
attribute.
2.5.13.3MIGRATION TO THE CCI
For XC8, change any occurrence of the #pragma psect directive, such as
#pragma psect text%%u=myText
int getMode(int target) {
//...
}
to the __section() specifier, as in
int __section ("myText") getMode(int target) {
//...
}
For 16- and 32-bit compilers, change any occurrence of the section attribute, as in
the following example:
int __attribute__((section("myVars"))) intMask;
to:
int __section("myVars") intMask;
2.5.13.4CAVEATS
With XC8, the __section() specifier cannot be used with any interrupt function.
DS52071B-page 44 2012 Microchip Technology Inc.
Common C Interface
2.5.14Specifying Configuration Bits
The #pragma config directive may be used to program the configuration bits for a
device. The pragma has the form:
#pragma config setting = state|value
#pragma config register = value
where setting is a configuration setting descriptor (e.g., WDT), state is a de scriptive
value (e.g., ON) and value is a numerical value. The register token may represent a
whole configuration word register, e.g., CONFIG1L.
Use the native keywords discussed in the Differences section to look up information on
the semantics of this directive.
2.5.14.1EXAMPLE
The following shows configuration bits being specified using this pragma.
#pragma config WDT=ON, WDTPS = 0x1A
2.5.14.2DIFFERENCES
The 8-bit compilers have used the __CONFIG() macro for some targets that did not
already have support for the #pragma config.
The 16-bit compilers have used a number of macros to specify the configuration set-
tings.
The 32-bit compilers supported the use of #pragma config.
2.5.14.3MIGRATION TO THE CCI
For the 8-bit compilers, change any occurrence of the __CONFIG() macro, such as
__CONFIG(WDTEN & XT & DPROT)
to the #pragma config directive, as in
#pragma config WDTE=ON, FOSC=XT, CPD=ON
No migration is required if the #pragma config was already used.
For the 16-bit compilers, change any occurrence of the _FOSC() or _FBORPOR()
The CCI defines the general form for macros that manifest the compiler and target
device characteristics. These macros can be used to conditionally compile alternate
source code based on the compiler or the target device.
The macros and macro families are details in Table 2-1.
TABLE 2-1:MANIFEST MACROS DEFINED BY THE CCI
NameMeaning if definedExample
__XC__Compiled with an MPLAB XC compiler__XC__
__CCI__Compiler is CCI compliant and CCI enforce-
ment is enabled
__XC##__The specific XC comp iler u sed (## c an be 8,
16 or 32)
__DEVICEFAMILY__The family of the selected target device__dsPIC30F__
2.5.15.2DIFFERENCES
Some of these CCI macros are new (for example __CCI__), and others have different
names to previous symbols with identical meaning (for example __18F452 is now
__18F452__).
2.5.15.3MIGRATION TO THE CCI
Any code which uses compiler-defined macros will need review. Old macros will con-
tinue to work as expected, but they are not compliant with the CCI.
2.5.15.4CAVEATS
None.
DS52071B-page 46 2012 Microchip Technology Inc.
Common C Interface
2.5.16In-line Assembly
The asm() statement may be used to insert assembly code in-line with C code. The
argument is a C string literal which represents a single assembly instruction. Obviously,
the instructions contained in the argument are device specific.
Use the native keywords discussed in the Differences section to look up information on
the semantics of this statement.
2.5.16.1EXAMPLE
The following shows a MOVLW instruction being inserted in-line.
asm("MOVLW _foobar");
2.5.16.2DIFFERENCES
The 8-bit compilers have used either the asm() or #asm ... #endasm constructs to
insert in-line assembly code.
This is the same syntax used by the 16- and 32-bit compilers.
2.5.16.3MIGRATION TO THE CCI
For 8-bit compilers change any instance of #asm ... #endasm so that each instruction
in this #asm block is placed in its own asm() statement, for example:
#asm
MOVLW 20
MOVWF _i
CLRFIi+1
#endasm
to
asm("MOVLW20");
asm("MOVWF _i");
asm("CLRFIi+1");
No migration is required for the 16- or 32-bit compilers.
2.5.16.4CAVEATS
None.
2012 Microchip Technology Inc.DS52071B-page 47
MPLAB® XC16 C Compiler User’s Guide
2.6COMPILER FEATURES
The following items detail compiler options and features that are not directly associated
with source code that
2.6.1Enabling the CCI
It is assumed you are using the MPLAB X IDE to build projects that use the CCI. The
widget in the MPLAB X IDE Project Properties to enable CCI conformance is Use CCI Syntax in the Compiler category. A widget with the same name is available in MPLAB
IDE v8 under the Compiler tab.
If you are not using this IDE, then the command-line options are --CCI for XC8 or
-mcci for XC16/32.
2.6.1.1DIFFERENCES
This option has never been implemented previously.
2.6.1.2MIGRATION TO THE CCI
Enable the option.
2.6.1.3CAVEATS
None.
DS52071B-page 48 2012 Microchip Technology Inc.
Chapter 3. Compiler Command-Line Driver
3.1INTRODUCTION
The compiler command-line driver (xc16-gcc ) is the application that invokes the oper-
ation of the MPLAB XC16 C Compiler. The driver compiles, assembles and links C and
assembly language modules and library archives. Most of the compiler command-line
options are common to all implementations of the GCC toolset. A few are specific to
the compiler and will be discussed below.
The compiler driver also may be used with MPLAB IDE. Compiler options are selected
in the GUI and passed to the compiler driver for execution.
Topics concerning the command-line use of the driver are discussed below. For more
on how to use the compiler with MPLAB IDE, please refer to the MPLAB Assembler,
Linker and Utilities for PIC24 MCUs and dsPIC DSCs User’s Guide (DS51317).
• Invoking the Compiler
• The Compilation Sequence
• Runtime Files
• Compiler Output
• Compiler Messages
• Driver Option Descriptions
• MPLAB IDE Toolsuite Equivalents
MPLAB® XC16 C COMPILER
USER’S GUIDE
2012 Microchip Technology Inc.DS52071B-page 49
MPLAB® XC16 C Compiler User’s Guide
3.2INVOKING THE COMPILER
The compiler is invoked and run on the command line as specified in the next section.
Additionally, environmental variables and input files used by the compiler are discussed
in the following sections.
3.2.1Drive Command-Line Format
The basic form of the compiler command line is:
xc16-gcc [options] files
where:
options: See Section 3.7 “Driver Option Descriptions” for available options.
files: See Section 3.2.3 “Input File Types” for details.
Note:Command line options and file name extensions are case-sensitive.
It is assumed in this manual that the compiler applications are either in the console’s
search path, see Section 3.2.2 “Environment Variables”, or the full path is specified
when executing any application.
It is conventional to supply options (identified by a leading dash “-”) before the file
names, although this is not mandatory.
The files may be any mixture of C and assembler source files, and precompiled intermediate files, such as relocatable object (.o) files. The order of the files is not important, except that it may affect the order in which code or data appears in memory.
For example, to compile, assemble and link the C source file hello.c, creating a relocatable object output, hello.out.
xc16-gcc -mcpu=30f2010 -o hello.out hello.c
3.2.2Environment Variables
The variables in this section are optional, but, if defined, they will be used by the
compiler. The compiler driver, or other subprogram, may choose to determine an
appropriate value for some of the following environment variables if they are unset. The
driver, or other subprogram, takes advantage of internal knowledge about the
installation of the compiler. As long as the installation structure remains intact, with all
subdirectories and executables remaining in the same relative position, the driver or
subprogram will be able to determine a usable value.
This variable’ s val ue is a sem icolo n-sep arate d list of dir ect ories, muc h
like PATH. When the compiler searches for header files, it tries the
directories listed in the variable, after the directories specified with -I
but before the standard header file directories.
If the environment vari able is und efined , the p reproce ssor choos es an
appropriate value based on the standard installation. By default, the
following directories are searched for include files:
<install-path>\include and
<install-path>\support\h
The value of the variable is a semicolon-separated list of directories,
much like PATH. The compiler tries the di rectori es th us sp ecifi ed when
searching for subprograms, if it can’t find the subprograms using
PIC30_EXEC_PREFIX.
TMPDIRIf the variable is set, it specifies the directory to use for temporary files.
If the environment variable is set, it specifies a prefix to use in the
names of subprograms executed by the compiler. No directory
delimiter is added when this prefix is combined with the name of a
subprogram, but you can specify a prefix that ends with a slash if you
wish. If the compiler cannot find the subprogram using the specified
prefix, it tries looking in your PATH environment variable.
If the environment variable is not set or set to an empty value, the
compiler driver chooses an appropriate value based on the standard
installation. If the installation has not been modified, this will result in
the driver being able to locate the required subprograms.
Other prefixes specified with the -B command line option take
precedence over the user- or driver-defined value of the variable.
Under normal circumstances it is best to leave this value undefined
and let the driver locate subprograms itself.
This variable’ s value i s a sem icolo n-sep arate d list of dir ectorie s, muc h
like PATH. This variable specifies a list of directories to be passed to
the linker. The driver’s default evaluation of this variable is:
<install-path>\lib; <install-path>\support\gld.
Specif ies the OMF (Object Module Format) to be used by the compiler .
By default, the tools create ELF object files. If the environment
variable has the value coff, the tools will create COFF object files.
The compiler uses temporary files to hold the output of one stage of
compilation that is to be used as input to the next stage: for example,
the output of the preprocessor, which is the input to the compiler
proper.
3.2.3Input File Types
The compilation driver distinguishes source files, intermediate files and library files
solely by the file type, or extension. It recognizes the following file extensions, which
are case-sensitive.
TABLE 3-2:FILE NAMES
ExtensionsDefinition
file.cA C source file that must be preprocessed.
file.hA header file (not to be compiled or linked).
file.iA C source file that should not be preprocessed.
file.oAn object file.
file.pA pre procedural-abstraction assembly language file.
file.sAssembler code.
file.SAssembler code that must be preprocessed.
otherA file to be passed to the linker.
There are no compiler restrictions imposed on the names of source files, but be aware
of case, name-length and other restrictions imposed by your operating system. If you
are using an IDE, avoid assembly source files whose basename is the same as the
basename of any project in which the file is used. This may result in the source file
being overwritten by a temporary file during the build process.
The terms “source file” and “module” are often used when talking about computer
programs. They are often used interchangeably, but they refer to the source code at
different points in the compilation sequence.
2012 Microchip Technology Inc.DS52071B-page 51
MPLAB® XC16 C Compiler User’s Guide
A source file is a file that contains all or part of a program. Source files are initially
passed to the preprocessor by the driver.
A module is the output of the preprocessor, for a given source file, after inclusion of any
header files (or other source files) which are specified by #include preprocessor
directives. These modules are then passed to the remainder of the compiler applications. Thus, a module may consist of several source and header files. A module is also
often referred to as a translation unit. These terms can also be applied to assembly
files, as they too can include other header and source files.
3.3THE COMPILATION SEQUENCE
How the compiler operates with other applications and how to perform different types
of compilations is discussed in the following sections.
3.3.1The Compiler Applications
The MPLAB XC16 C Compiler compiles C source files, producing assembly language
files. These compiler-generated files are assembled and linked with other object files
and libraries to produce the final application program in executable ELF or COFF file
format. The ELF or COFF file can be loaded into the MPLAB IDE, where it can be
tested and debugged, or the conversion utility can be used to convert the ELF or COFF
file to Intel
programmer. See Figure 3-1 for an overview of the software development data flow.
®
hex format, suitable for loading into the command-line simulator or a device
DS52071B-page 52 2012 Microchip Technology Inc.
Compiler Command-Line Driver
Object File Libraries
(*.a)
Assembler
Linker
C Source Files
(*.c)
C Compiler
Assembly Source
Files (*.S)
Debug File
(*.cof,*.elf)
Archiver (Librarian)
Compiler
Driver
Program
MPLAB® X IDE
Debug T ool
Source Files (*.s)
Object Files
(*.o)
Command-Line
Simulator
Linker Script File
(1)
(*.ld)
Executable File
(*.hex)
MPLAB X IDE
Programmer
bin2hex Utility
Output File
(*.out)
Note 1:The linker can choose the correct linker script file for your project.
FIGURE 3-1:SOFTWARE DEVELOPMENT TOOLS DATA FLOW
The driver program will call the required internal compiler applications. These applica-
tions are shown as the smaller boxes inside the large driver box. The temporary file pro-
duced by each application can also be seen in this diagram.
Table 3-3 lists the compiler applications. The names shown are the names of the exe-
cutables, which can be found in the bin directory under the compiler’s installation
directory. Your PATH environment variable should include this directory.
2012 Microchip Technology Inc.DS52071B-page 53
MPLAB® XC16 C Compiler User’s Guide
TABLE 3-3:COMPILER APPLICATION NAMES
NameDescription
xc16-gccCommand line driver; the interface to the compiler
xc16-cc1Code generator (elf by default)
xc16-asAssembler (based on the target device)
xc16-ldLinker
xc16-bin2hexConversion utility to create HEX files
xc16-stringsString extractor utility
A single command-line instruction can be used to compile one file or multiple files.
3.3.2.1COMPILING A SINGLE FILE
This section demonstrates how to compile and link a single file. For the purpose of this
discussion, it is assumed the compiler is installed in the standard directory location and
that your P A TH or other enviro nment variab les (see Section 3.2.2 “Environment Vari-ables”) are set up in such a way that the full compiler path need not be specified when
you run the compiler.
The following is a simple C program that adds two numbers.
Create the following program with any text editor and save it as ex1.c.
#include <xc.h>
int main(void);
unsigned int Add(unsigned int a, unsigned int b);
unsigned int x, y, z;
int
main(void)
{
x = 2;
y = 5;
z = Add(x,y);
return 0;
}
unsigned int
Add(unsigned int a, unsigned int b)
{
return(a+b);
}
The first line of the program includes the header file xc.h, which will include the appropriate header files that provides definitions for all special function registers on the target
device. For more information on header files, see Section 4.3 “Device Header Files”.
Compile the program by typing the following at the prompt in your favorite terminal.
xc16-gcc -mcpu=30f2010 -o ex1.out ex1.c
The command-line option -o ex1.out names the output executable file (if the -o
option is not specified, then the output file is named a.out). The executable file may
be loaded into the MPLAB IDE.
Symbol stripper utility
Symbol list utility
DS52071B-page 54 2012 Microchip Technology Inc.
Compiler Command-Line Driver
If a hex file is required, for example, to load into a device programmer, then use the
following command:
xc16-bin2hex ex1.out
This creates an Intel hex file named ex1.hex.
3.3.2.2COMPILING MULTIPLE FILES
Move the Add() function into a file called add.c to demonstrate the use of multiple
files in an application. That is:
File 1
/* ex1.c */
#include <xc.h>
int main(void);
unsigned int Add(unsigned int a, unsigned int b);
unsigned int x, y, z;
int main(void)
{
x = 2;
y = 5;
z = Add(x,y);
return 0;
}
File 2
/* add.c */
#include <xc.h>
unsigned int
Add(unsigned int a, unsigned int b)
{
return(a+b);
}
Compile both files in the one command by typing the following in your terminal program.
xc16-gcc -mcpu=30f2010 -o ex1.out ex1.c add.c
This command compiles the modules ex1.c and add.c. The compiled modules are
linked with the compiler libraries and the executable file ex1.out is created.
3.3.3Multi-Step Compilation
Make utilities and integrated development environments, such as MPLAB IDE, allow
for an incremental build of projects that contain multiple source files. When building a
project, they take note of which source files have changed since the last build and use
this information to speed up compilation.
For example, if compiling two source files, but only one has changed since the last
build, the intermediate file corresponding to the unchanged source file need not be
regenerated.
If the compiler is being invoked using a make utility, the make file will need to be con-
figured to recognized the different intermediate file format and the options used to gen-
erate the intermediate files. Make utilities typically call the compiler multiple times: once
for each source file to generate an intermediate file, and once to perform the second
stage compilation.
You may also wish to generate intermediate files to construct your own library files,
although xc16-gcc is capable of constructing libraries so this is typically not neces-
sary. See MPLAB Assembler, Linker and Utilities for PIC24 MCUs and dsPIC DSCs
User’s Guide (DS5 131 7) for more information on library creation.
2012 Microchip Technology Inc.DS52071B-page 55
MPLAB® XC16 C Compiler User’s Guide
For exampl e, the files ex1.c and add.c are to be compiled using a make utility. The
command lines that the make utility should use to compile these files might be something like:
The -c option will compile the named file into the intermediate (object) file format, but
not link. Once all files are compiled as specified by the make, then the resultant object
files are linked in the final step to create the final output ex1. The above example uses
the command-line driver, xc16-gcc, to perform the final link step. You can explicitly
call the linker application, xc16-ld, but this is not recommended. When driving the linker
application, you must specify linker options, not driver options. For more on using the
linker, see MPLAB Assembler, Linker and Utilities for PIC24 MCUs and dsPIC DSCs User’s Guide (DS5 131 7) .
When compiling debug code, the object module format (OMF) must be consistent for
compilation, assembly and linking. The ELF/DWARF format is used by default but the
COFF format may also be selected using -omf=coff or the environmental variable
XC16_OMF.
3.3.4Assembly Compilation
A mix of C and assembly code can be compiled together using the compiler
(Figure 3-1). For more details, see Chapter 13. “Mixing C and Assembly Code”.
Additionally, the compiler may be used to generate assembly code (.s) from C code
(.c) using the -S option. The assembly output may then be used in subsequent compilation using the command-line driver.
DS52071B-page 56 2012 Microchip Technology Inc.
3.4RUNTIME FILES
The compiler uses the following files in addition to source, linker and header files.
3.4.1Library Files
The compiler may include library files into the output per Figure 3-1.
By default, xc16-gcc will search directories under the compiler installation directory
for library files that are required during compilation.
3.4.1.1STANDARD LIBRARIES
The C standard libraries contain a standardized collection of functions, such as string,
math and input/output routines. The range of these functions are described in the
“16-Bit Language Tool Libraries” (DS5145 6 ).
3.4.1.2USER-DEFINED LIBRARIES
Users may create their own libraries. Libraries are useful for bundling and precompiling
selected functions so that application file management is easier and application com-
pilation times are shorter.
Libraries can be created manually using the compiler and the librarian. To create files
that may then be used as input to the 16-bit librarian (xc16-ar), use the -c compiler
option to stop compilation before the linker stage. For information on using the librarian,
see the MPLAB Assembler, Linker and Utilities for PIC24 MCUs and dsPIC DSCs
User’s Guide (DS5 131 7) .
User-created libraries that should be searched when building a project can be listed on
the command line along with the source files.
As with Standard C library functions, any functions contained in user-defined libraries
should have a declaration added to a header file. It is common practice to create one
or more header files that are packaged with the library file. These header files can then
be included into source code when required.
Library files specified on the command line are scanned first for unresolved symbols,
so these files may redefine anything that is defined in the C standard libraries.
Compiler Command-Line Driver
3.4.2Startup and Initialization
Two startup modules are available to initialize the C runtime environment:
• The primary startup module (crt0.o) which is linked by default (or the -Wl,
--data-init option.)
• The alternate startup module (crt1.o) which is linked when the -Wl,
--no-data-init option is specified (no data initialization.)
These modules are included in the libpic30-omf.a archive/library . Mult iple versions
of these modules exist in order to support architectural differences between device
families. The compiler automatically uses the correct module.
For more information on the startup modules, see Section 12.3 “Runtime Startup
and Initialization”.
2012 Microchip Technology Inc.DS52071B-page 57
MPLAB® XC16 C Compiler User’s Guide
3.5COMPILER OUTPUT
There are many files created by the compiler during the compilation. A large number of
these are intermediate files are deleted after compilation is complete, but many remain
and are used for programming the device or for debugging purposes.
3.5.1Output Files
The compilation driver can produce output files with the following extensions, which are
case-sensitive.
The names of many output files use the same base name as the source file from which
they were derived. Fo r examp le the sour ce file input.c will create an object file called
input.o when the -c option is used.
The default output file is a ELF file called a.out, unless you override that name using
the -o option.
If you are using an IDE, such as MPLAB IDE, to specify options to the compiler, there
is typically a project file that is created for each application. The name of this project is
used as the base name for project-wide output files, unless otherwise specified by the
user. However check the manual for the IDE you are using for more details.
Note:Throughout this manual, the term project name will refer to the name of the
project created in the IDE.
The compiler is able to directly produce a number of the output file formats which are
used by Microchip develop men t tools .
The default behavior of xc16-gcc is to produce a ELF output. T o make changes to the
files output or the file names, see Section 3.7 “Driver Optio n Descr ip tions ”.
3.5.2Diagnostic Files
Two valuable files produced by the compiler are the assembly list file, produced by the
assembler, and the map file, produced by the linker.
The assembly list file contains the mapping between the original source code and the
generated assembly code. It is useful for information such as how C source was
encoded, or how assembly source may have been optimized. It is essential when confirming if compiler-produced code that accesses objects is atomic, and shows the
region in which all objects and code are placed.
The option to create a listing file in the assembler is -a. There are many variants to this
option, which may be found in the MPLAB Assembler, Linker and Utilities for PIC24 MCUs and dsPIC DSCs User’s Guide (DS51317). To pass the option from the compiler,
see Section 3.7.8 “Options for Assembling”.
DS52071B-page 58 2012 Microchip Technology Inc.
There is one list file produced for each build. Thus, if you require a list file for each
source file, these files must be compiled separately, see Section 3.3.3 “Multi-Step
Compilation”. This is the case if you build using MPLAB IDE. Each list file will be
assigned the module name and extension .lst.
The map file shows in formatio n relati ng to wh ere obje cts were positio ned in me mory. It
is useful for confirming if user-defined linker options were correctly processed, and for
determining the exact placement of objects and functions.
The linker option to create a map file in the linker application is -Map file, which may
be found in the MPLAB As se mbl er, Linker and Utilities for PIC24 M CUs and dsPIC
DSCs User’s Guide (DS51317). To specify the option from the command-line driver,
see Section 3.7.9 “Options for Linking”.
There is one map file produced when you build a project, assuming the linker was exe-
cuted and ran to completion.
3.6COMPILER MESSAGES
Compiler output messages for errors, warnings or comments as discussed in Appen-
dix B. “Diagnostics”.
For information on options that control compiler output of errors, warnings or com-
ments, see Section 3.7.4 “Options for Controlling Warnings and Errors”.
There are no pragmas that directly control messages issued by the compiler.
Compiler Command-Line Driver
2012 Microchip Technology Inc.DS52071B-page 59
MPLAB® XC16 C Compiler User’s Guide
3.7DRIVER OPTION DESCRIPTIONS
The compiler has many options for controlling compilation, all of which are
case-sensitive. They have been grouped, as shown below, according to their function.
Remember, these are options for the command-line driver; options for the linker,
assembler or any other application can be found in the MPLAB Assembler, Linker and Utilities for PIC24 MCUs and dsPIC DSCs User’s Guide (DS51317).
• Options Specific to 16-Bit Devices
• Options for Controlling the Kind of Output
• Options for Controlling the C Dialect
• Options for Controlling Warnings and Errors
• Options for Debugging
• Options for Controlling Optimization
• Options for Controlling the Preprocessor
• Options for Assembling
• Options for Linking
• Options for Directory Search
• Options for Code Generation Conventions
3.7.1Options Specific to 16-Bit Devices
For more information on the memory models, see Section 7.12 “Memory Models”.
TABLE 3-5:16-BIT DEVICE-SPECIFIC OPTIONS
OptionDefinition
-mconst-in-code Put const qualified variables in the auto_psv space. The compiler
will access these variables using the PSV window. (This is the
default.)
-mconst-in-data Put const qualified variables in the data memory space.
-mconst-in-
auxflash
-merrata=
id[,id]*
-mfillupperSpecif y the up per byte of variab les st ored into space(prog) sections.
Note 1: The procedure abstractor behaves as the inverse of inlining f unctions. The pass is
designed to extract common code sequences from multiple sites throughout a
translation unit and place them into a common area of code. Although this option
generally does no t im pro ve the run -tim e p erformance of the gene rate d c ode , it ca n
reduce the code size significantly. Programs compiled with -mpa can be harder to
debug; it is not recommended that this option be used while debugging using the
COFF object format.
The procedure abstractor is invoked as a separate phase of compilation, after the
production of an assembly file. This phase does not optimize across translation
units. When the proc edure-opti mizing ph ase is enabl ed, inline as sembly cod e must
be limited to valid machine instructions. Invalid machine instructions or instruction
sequences, or assemb ler dire ct ive s (se cti oni ng directives, macros, include f ile s,
etc.) must not be used, or the procedure abstraction phase will fail, inhibiting the
creation of an output file.
When combined with -mconst-in-code, put call const qualified file
scope variables i nto auxil iary FLASH. Al l modules with auxil iary FLASH
should be compiled with this option; otherwise a link error may occur.
This option enabl es sp ec ific er rat a work arounds identified by id. Valid
values for id change from time to time and may not be required for a
particular variant. An id of list will display the currently supported
errata identifiers along with a brief description of the errata. An id of all will enable all currently supported errata work arounds.
The fillupper attribute will perform the same function on individual
variables.
-mlarge-arraysSpecifies that arrays may be larger than the default maximum size of
32K. See Section 4.7 “Bit-Reversed and Modulo Addressing” for
more information.
-mlarge-codeCompile using the large code model. No assumptions are made about
the locality of called functions.
When this option is chosen, single functions that are larger than 32k
are not supported and may cause assembly-time errors since all
branches inside of a function are of the short form.
-mlarge-dataCompile using the large data model. No assumptions are made about
the location of static and external variables.
-mcpu=
target
(1)
-mpa
-mpa=n
-mno-pa
-mno-isr-warnBy default the compiler will produce a warning if the
-omfSelects the OMF (Object Module Format) to be used by the compiler.
-msmall-codeCompile using the small code model. Called functions are assumed to
Note 1: The procedure abstractor behaves as the inverse of inlining f unctions. The pass is
(1)
(1)
designed to extract common code sequences from multiple sites throughout a
translation unit and place them into a common area of code. Although this option
generally does no t im pro ve the run -tim e p erformance of the gene rate d c ode , it ca n
reduce the code size significantly. Programs compiled with -mpa can be harder to
debug; it is not recommended that this option be used while debugging using the
COFF object format.
The procedure abstractor is invoked as a separate phase of compilation, after the
production of an assembly file. This phase does not optimize across translation
units. When the proc edure-opti mizing pha se is enabl ed, inline as sembly cod e must
be limited to valid machine instructions. Invalid machine instructions or instruction
sequences, or assemb ler dire ct ive s (se cti oni ng directives, macros, include files,
etc.) must not be used, or the procedure abstraction phase will fail, inhibiting the
creation of an output file.
This option selects the target processor ID (and communicates it to the
assembler and linker if tho se tools are invo ked). This optio n affect s how
some predefined constants are set; see Section 16.4 “Predefined Macro Names” for more info rmation. A full list of accepted t arg et s can
be seen in the Readme.htm file that came with the release.
Enable the procedure abstraction optimization. There is no limit on the
nesting level.
Optimization levels depend on the compiler edition (see Chapter
15. “Optimizations”.)
Enable the procedure ab straction optimiza tion up to lev el n. If n is zero,
the optimization is disabled. If n is 1, first level of abs traction is allowed;
that is, instruction sequences in the source code may be abstracted
into a subroutine. If n is 2, a second level of abs tracti on is allow ed; tha t
is, instructions that were put into a subroutine in the first level may be
abstracted into a subroutin e one lev el dee per. This pattern continues
for larger values of n. The net effect is to limit the subroutine call nesting depth to a maximum of n.
Optimization levels depend on the compiler edition (see Chapter
15. “Optimizations”.)
Do not enable the procedure abstraction optimization.
(This is the default.)
__interrupt__
is not attached to a recognized interrupt vector name. This option will
disable that feature.
The omf specifier can be one of the following:
elfProduce ELF object files. (This is the default.)
coffProduce COFF object files.
The debugging format used for ELF object files is DWARF 2.0.
be proximate (within 32 Kwords of the caller). (This is the default.)
-msmall-dataCompile using the small data model. All static and external variables
are assumed to be located in the lower 8 KB of data memory space.
(This is the default.)
-msmall-scalarLike -msmall-data, except that only static and external scalars are
assumed to be in the lower 8 KB of data memory space. (This is the
default.)
-mtext=nameSpecifying -mtext=name will cause text (program code) to be placed
in a section named name rather than the default .text section. No
white spaces should appear around the =.
-mauxflashPlace all code from the current translation unit into auxiliary FLASH.
This option is only available on devices that have auxiliary FLASH.
-msmart-io
[=0|1|2]
Note 1: The procedure abstractor behaves as the inverse of inlining f unctions. The pass is
designed to extract common code sequences from multiple sites throughout a
translation unit and place them into a common area of code. Although this option
generally does no t im pro ve the run -tim e p erformance of the gene rate d c ode , it ca n
reduce the code size significantly. Programs compiled with -mpa can be harder to
debug; it is not recommended that this option be used while debugging using the
COFF object format.
The procedure abstractor is invoked as a separate phase of compilation, after the
production of an assembly file. This phase does not optimize across translation
units. When the proc edure-opti mizing ph ase is enabl ed, inline as sembly cod e must
be limited to valid machine instructions. Invalid machine instructions or instruction
sequences, or assemb ler dire ct ive s (se cti oni ng directives, macros, include f ile s,
etc.) must not be used, or the procedure abstraction phase will fail, inhibiting the
creation of an output file.
This option attempts to statically analyze format strings passed to
printf, scanf and the ‘f’ and ‘v’ variati ons of thes e function s. Uses of
nonfloating point format arguments will be converted to use an
integer-only variation of the library functions.
-msmart-io=0 disables this op tion, whi le -msmart-io=2 causes the
compiler to be optimistic and convert function calls with variable or
unknown format argument s . -msmart-io=1 is the default and will
only convert the literal values it can prove.
3.7.2Options for Controlling the Kind of Output
The following options control the kind of output produced by the compiler.
TABLE 3-6:KIND-OF-OUTPUT CONTROL OPTIONS
OptionDefinition
-cCompile or assemble the source files, but do not link. The default file extension
is .o.
-EStop after the prepro cess ing st age, i .e., before runnin g the comp iler pro per. The
default output file is stdout.
-o filePlace the output in file.
-SStop after compilation proper (i.e., before invoking the assembler). The default
output file extension is .s.
-vPrint the commands executed during each stage of compilation.
DS52071B-page 62 2012 Microchip Technology Inc.
Compiler Command-Line Driver
TABLE 3-6:KIND-OF-OUTPUT CONTROL OPTIONS (CONTINUED)
OptionDefinition
-xYou can specify the input language explicitly with the -x option:
-x
language
Specify explicitly the language for the following input files (rather than
letting the compiler choose a default based on the file name suffix). This option
applies to all following input files until the next -x option.
The following values are supported by the compiler:
c c-header cpp-output
assembler assembler-with-cpp
-x none
Turn off any specification of a language, so that subsequent files are handled
according to their file name s uff ixes. This is the defaul t beh avior but is neede d if
another -x option has been used.
For example:
Without the -x none, the compiler will assume all the input files are for the
assembler.
--helpPrint a description of the command line options.
3.7.3Options for Controlling the C Dialect
The following options define the kind of C dialect used by the compiler.
TABLE 3-7:C DIALECT CONTROL OPTIONS
OptionDefinition
-ansiSupport all (and only) ANSI-standard C programs.
-aux-info filenameOutput to the gi ven file n ame prototy ped d eclara tio ns for a ll
functions declared and/or defined in a translation unit,
including those in header files. This option is silently
ignored in any language other than C. Besides
declarations, the file indicate s, in com m ents, the origin of
each declaration (source fi le and lin e), whe ther the declar ation was implicit, prototyped or unprototyped (I, N for new
or O for old, respectively, in the first character after the line
number and the colon), and whether it came from a
declaration or a definition (C or F, respectively, in the
following character). In the case of function definitions, a
K&R-style list of argum ents followed by their dec larations is
also provided, inside comment s , af ter the dec la rati on.
-ffreestandingAssert that compilation takes place in a freestanding
environment. This implies -fno-builtin. A freestanding
environment is one in which the standard library may not
exist, and program sta rtup may not nec essari ly be at mai n.
The most obvious example is an OS kernel. This is
equivalent to -fno-hosted.
-fno-asmDo not recognize asm, inline or typeof as a keyword,
so that code can use these words as identifiers. You can
use the keywords
__typeof__ instead.
-ansi implies -fno-asm.
-fno-builtin
-fno-builtin-function
-fsigned-charLet the type char be signed, like signed char.
Don’t recognize built-in functions that do not begin with
__builtin_ as prefix.
(This is the default.)
__asm__, __inline__ and
2012 Microchip Technology Inc.DS52071B-page 63
MPLAB® XC16 C Compiler User’s Guide
TABLE 3-7:C DIALECT CONTROL OPTIONS (CONTINUED)
OptionDefinition
-fsigned-bitfields
-funsigned-bitfields
-fno-signed-bitfields
-fno-unsigned-bitfields
-funsigned-charLet the type char be unsigned, like unsigned char.
3.7.4Options for Controlling Warnings and Errors
Warnings are diagnostic messages that report constructions that are not inherently
erroneous but that are risky or suggest there may have been an error.
You can request many specific warnings with options beginning -W, for example,
-Wimplicit, to request warnings on implicit declarations. Each of these specific
warning options also has a negative form beginning -Wno- to turn off warnings, for
example, -Wno-implicit. This manual lists only one of the two forms, whichever is
not the default.
The following options control the amount and kinds of warnings produced by the
compiler.
TABLE 3-8:WARNING/ERROR OPTIONS IMPLIED BY -WALL
OptionDefinition
-fsyntax-onlyCheck the code for syntax, but don’t do anything beyond that.
-pedanticIssue all the warnings demanded by strict ANSI C; reject all
-pedantic-errorsLike -pedantic, except that errors are produced rather than
-wInhibit all warning messages.
-WallAll of the -W options listed in this table combined. This enables
-Wchar-subscriptsWarn if an array subscript has type char.
-Wcomment
-Wcomments
-Wdiv-by-zeroWarn about compile-time integer division by zero. To inhibit the
-Werror-implicit function-declaration
-WformatCheck calls to printf and scanf, etc., to make sure that the
-WimplicitEquivalent to specifying both -Wimplicit-int and
-Wimplicit-function declaration
-Wimplicit-intWarn when a declaration does not specify a type.
These options control whether a bit field is signed or
unsigned, when the declaration does not use either signed
or unsigned. By default, such a bit field is signed, unless
-traditional is used, in which case bi t fields are alw ays
unsigned.
programs that use forbidden extensions.
warnings.
all the warnings about constructions that some users consider
questionable, and that are easy to avoid (or modify to prevent
the warning), even in conjunction with macros.
Warn whenever a comment-start sequence /* appears in a /*
comment, or whenever a Backslash-Newline appears in a //
comment.
warning messages, use -Wno-div-by-zero. Floating point
division by zero is not warned about, as it can be a legitimate
way of obtaining infinities and NaNs.
(This is the default.)
Give an error whenever a function is used before being
declared.
arguments supplied have types appropriate to the format string
specified.
-Wimplicit-function-declaration.
Give a warning whenever a function is used before being
declared.
DS52071B-page 64 2012 Microchip Technology Inc.
Compiler Command-Line Driver
TABLE 3-8:WARNING/ERROR OPTIONS IMPLIED BY -WALL (CONTINUED)
OptionDefinition
-WmainWarn if the type of main is suspicious. main should be a func-
tion with external linkage, re turn ing int, taking either zero, two
or three arguments of appropriate types.
-Wmissing-bracesWarn if an aggregat e or un ion i nit ializer i s no t fully brac keted . In
the following example, the initializer for a is not fully bracketed,
but that for b is fully bracketed.
-WparenthesesWarn if parentheses are omitted in certain contexts, such as
-Wreturn-typeWarn whenever a function is defined with a return-type that
Warn if a multi-character character constant is used.
Usually, such constants are typographical errors. Since they
have implementati on-define d values, they sho uld not be used in
portable code. The following example illustrates the use of a
multi-character character constant:
char
xx(void)
{
return('xx');
}
when there is an assign me nt in a context where a truth val ue i s
expected, or when operators are nested whose precedence
people often find confusing.
defaults to int. Also w arn about any return st atement with no
return-value in a function whose return-type is not void.
2012 Microchip Technology Inc.DS52071B-page 65
MPLAB® XC16 C Compiler User’s Guide
TABLE 3-8:WARNING/ERROR OPTIONS IMPLIED BY -WALL (CONTINUED)
OptionDefinition
-Wsequence-pointWarn about code that may have undefined semantics because
of violations of sequence point rules in the C standard.
The C standard defines the order in which expressions in a C
program are evaluated in terms of sequence points, which represent a partial ordering between the execution of parts of the
program: those executed before the sequence point and those
executed after it. These occur after the evaluation of a full
expression (one which is not part of a larger expression), after
the evaluation of the first operand of a &&, ||, ? : or ,
(comma) operator, before a function is called (but after the eva luation of its arguments and the expression denoting the called
function), and in certain other places. Other than as expressed
by the sequence point rules, the order of evaluation of subexpressions of an expression is not specified. All these rules
describe only a partial order rather than a total order, since, for
example, if two functions are called within one expression with
no sequence point between them, the order in which the functions are called is not specified. However, the standards committee has ruled that function calls do not overlap.
It is not specified, when, between sequence points
modifications to the values of objects take effect. Programs
whose behavior depends on this have undefined behavior; the
C standard specifies that “Between the previous and next
sequence point, an object shall have its stored value modified,
at most once, by the evaluation of an expres si on. Furt herm ore ,
the prior value shall be read only to determine the value to be
stored.” If a program breaks these rules, the results on any particular implementati on are enti rel y unpre di ct a ble.
Examples of code with undefined behavior are a = a++;, a[n] = b[n++] and a[i++] = i;. Some more complicated
cases are not diagnosed by this option, and it may give an
occasional fals e posi tive re sult, b ut in g eneral it has been f ound
fairly effective at detecting this sort of problem in programs.
-WswitchWarn whenever a switch statement has an index of enumeral
type and lacks a case for one or more of the named codes of
that enumeration. (Th e pres ence of a de fault l abel p revents this
warning.) case labels outside the enumeration range also provoke warn ings when this option is used.
-Wsystem-headersPrint warning messages for constructs found in system header
files. Warnings from system headers are normally suppressed,
on the assumption that they usually do not indicate real problems and would only make the compiler output harder to read.
Using this command line option tells the compiler to emit warnings from system headers as if they occurred in user code.
However, note that using -Wall in conjunction with this option
will not warn about unknown pragmas in system headers; for
that, -Wunknown-pragmas must also be used.
-WtrigraphsWarn if any trigraphs are encountered (assuming they are
enabled).
DS52071B-page 66 2012 Microchip Technology Inc.
Compiler Command-Line Driver
TABLE 3-8:WARNING/ERROR OPTIONS IMPLIED BY -WALL (CONTINUED)
OptionDefinition
-WuninitializedWarn if an automatic variable is used without first being
initialized.
These warnings are pos sible only wh en optimizat ion is enable d,
because they require data flow information that is computed
only when optimizing.
These warnings occur only for variables that are candidates for
register allocation . Therefore, they do not occur for a v ariable
that is declared volatile, or whose address is taken, or
whose size is other than 1, 2, 4 or 8 bytes. Also, they do not
occur for structures, unions or arrays, even when they are in
registers.
Note that there may be no warn ing abo ut a v ariable that i s use d
only to compute a value that itself is never used, because such
computations may be deleted by data flow analysis before the
warnings are printed.
-Wunknown-pragmasWarn when a #pragma directive is encountered which is not
understood by the compi ler. If this command line option is used,
warnings will even be issued for unknown pragmas in system
header files. This is not the case if the warnings were only
enabled by the -Wall command line option.
-WunusedWarn whenever a variable is unused aside from its declaration,
whenever a function is declared static but never defined, whenever a label is declared but not used, and whenever a statement computes a result that is explicitly not used.
In order to get a warning about an unused function parameter,
both -W and -Wunused must be specified.
Casting an expression to void suppresses this warning for an
expression. Similarly, the unused attribute suppresses this
warning for unused var iables, para meters and labels.
-Wunused-functionWarn whene ver a st atic func tion is d eclare d but not defin ed or a
non-inline static fun cti on is unu sed.
-Wunused-labelWarn whenever a label is declared but not used. To suppress
this warning, use the unused attribute (see
Section 6.11 “Variable Attributes”).
-Wunused-parameterWarn whenever a function parameter is unused aside from its
declaration. To suppress this warning, use the unused attribute
(see Section 6.11 “Variable Attributes”).
-Wunused-variableWarn whenever a local variable or non-constant static variable
is unused aside from its declaration. To suppress this warning,
use the unused attribute (see Section 6.11 “Variable Attri-butes”).
-Wunused-valueWarn whenever a statement computes a result that is explicitly
not used. To suppress this warning, cast the expression to
void.
The following -W options are not implied by -Wall. Some of them warn about constructions that users generally do not consider questionable, but which occasionally you
might wish to check for. Others warn about constructions that are necessary or hard to
avoid in some cases, and there is no simple way to modify the code to suppress the
warning.
2012 Microchip Technology Inc.DS52071B-page 67
MPLAB® XC16 C Compiler User’s Guide
TABLE 3-9:WARNING/ERROR OPTIONS NOT IMPLIED BY -WALL
OptionDefinition
-WPrint extra warning messages for these events:
• A nonvolatile automatic variable might be changed by a
call to longjmp. These warnings are possible only in
optimizing compilation. The compiler sees only the calls
to setjmp. It can not know where longjmp will be called;
in fact, a signal handler could call it at any point in the
code. As a result, a warning may be generated even
when there is in fact no problem, because longjmp
cannot in fact be called at the place that would cause a
problem.
• A function could exit both via return value; and
return;. Completing the function body without passing
any return statement is treated as return;.
• An expression-statement or the left-hand side of a
comma expression contains no side effects. To suppress
the warning, cast the unused expression to void. For
example, an expression such as x[i,j] will cause a
warning, but x[(void)i,j] will not.
• An unsigned value is compared against zero with < or <=.
• A comparison like x<=y<=z appe ars; thi s is equiv alent to
(x<=y ? 1 : 0) <= z, which is a different interpretation
from that of ordinary mathematical notation.
• Storage-class specifiers like static are not the first
things in a declaration. According to the C Standard, this
usage is obsolescent.
•If -Wall or -Wunused is also specified, warn about
unused arguments .
• A comparison between s igned and uns igned value s could
produce an incorrect result when the signed value is
converted to unsigned. (But don’t warn if
-Wno-sign-compare is also specified.)
• An aggregate has a partly bracketed initializer. For
example, the follow ing code w ould ev oke such a warning,
because braces are mi ss ing around the initiali zer for x.h:
struct s { int f, g; };
struct t { struct s h; int i; };
struct t x = { 1, 2, 3 };
• An aggregate has an initializer that does not initialize all
members. For example, the following code would cause
such a warnin g, because x.h would be implicitly
initialized to zero:
struct s { int f, g, h; };
struct s x = { 3, 4 };
-Waggregate-returnWarn if any functions that return structures or unions are
defined or called.
-Wbad-function-castWarn whenev er a fu nc tio n call is cast to a non-ma tch ing type.
For example, warn if int foof() is cast to anything *.
-Wcast-alignWarn whenever a pointer is cast, such tha t the required
alignment of the target is increased. For example, warn if a
char * is cast to an int * .
-Wcast-qualWarn whenever a pointer is cast, so as to remove a type
qualifier from the target type. For example, warn if a
const char * is cast to an ordinary char *.
DS52071B-page 68 2012 Microchip Technology Inc.
Compiler Command-Line Driver
TABLE 3-9:WARNING/ERROR OPTIONS NOT IMPLIED BY -WALL
OptionDefinition
-WconversionWarn if a prototype causes a type conversion that is different
from what would happen to the same argument in the
absence of a prototype. This includes conversions of fixed
point to floating an d vic e versa, a nd con versi ons ch angin g th e
width or signedness of a fixed point argument, except when
the same as the default promotion.
Also, warn if a negative integer co nstant expres sion is
implicitly converted to an unsigned type. For example, warn
about the assignment x = -1 if x is unsigned. But do not
warn about explicit casts like (unsigned) -1.
-WerrorMake all warnings into errors.
-WinlineWarn if a function can not be inlined, and either it was
declared as inline, or else the -finline-functions option
was given.
-Wlarger-than-lenWarn whene ver an obj ec t of larger than len bytes is defined.
-Wlong-long
-Wno-long-long
-Wmissing-declarations Warn if a global function is defined without a previous
-Wmissing-
format-attribute
-Wmissing-noreturnWarn about functions that might be candidates for attribute
-Wmissing-prototypesWarn if a global function is defined without a previous
-Wnested-externsWarn if an extern declaration is encountered within a
-Wno-deprecated-
declarations
-WpaddedWarn if padding is included in a structure, either to align an
-Wpointer-arithWarn about anything that depends on the size of a function
-Wredundant-declsWarn if anything is declared more than once in the same
-WshadowWarn whenever a local variable shadows another local
Warn if long long type is used. This is default. To inhibit the
warning messages, use -Wno-long-long. Flags
-Wlong-long and -Wno-long-long are taken into ac count
only when -pedantic flag is used.
declaration. Do so even if the definition itself provides a
prototype.
If -Wformat is enabled, also warn about functions that might
be candidates for format attributes. Note these are only possible candidates, not absolute ones. This option has no effect
unless -Wformat is enabled.
noreturn. These are only possible candidates, not absolute
ones. Care should be taken to manually verify functions.
Actually, do not ever return before adding the noreturn attri-
bute; otherwise subtle code generation bugs could be introduced.
prototype declaration. This warning is issued even if the
definition itse lf pro vi des a prot oty pe. (This opti on can be us ed
to detect global fu nctions t hat are not d eclared i n heade r files .)
function.
Do not warn about uses of functions, variables and types
marked as deprecated by using the deprecated attribute.
element of the structure or to align the whole structure.
type or of void. The compiler assigns these types a siz e of 1,
for convenience in calculations with void * pointers and
pointers to functions.
scope, even in cases where multiple declaration is valid and
changes nothing.
variable.
2012 Microchip Technology Inc.DS52071B-page 69
MPLAB® XC16 C Compiler User’s Guide
TABLE 3-9:WARNING/ERROR OPTIONS NOT IMPLIED BY -WALL
OptionDefinition
-Wsign-compare
-Wno-sign-compare
-Wstrict-prototypesWarn if a func tion i s decla red or defi ned wi thout s peci fying the
-WtraditionalWarn about certain constructs that behave differently in
-WundefWarn if an undefined identifier is evaluated in an #if
-Wwrite-stringsGive string constants the ty pe const char[length] so tha t
Warn when a comparison between signed and unsigned
values could produce an incorre ct resu lt w hen the signe d
value is converted to unsigned. This warning is also enabled
by -W; to get the other warnings of -W without this warning,
use -W -Wno-sign-compare.
argument types. (An old-style function definition is permitted
without a warning i f preced ed by a decl aration which s peci fies
the argument types.)
traditional and ANSI C.
• Macro arguments occurring within string constants in the
macro body. These would substitute the argument in
traditio nal C, but ar e part of the constant in ANSI C.
• A function declared external in one block and then used
after the end of the block.
• A switch statement has an operand of type long.
• A nonstatic function declaration follows a static one. This
construct is not accepted by some traditional C compilers.
directive.
copying the address of one into a non-const char * pointer
will get a warning. The se warnings will help you find at
compile time code that you can try to write into a string
constant, but only if you have been very careful about using
const in declarations and prototype s. Otherwise, it will just be
a nuisance, which is why -Wall does not request these
warnings.
3.7.5Options for Debugging
The following options are used for debugging.
TABLE 3-10:DEBUGGING OPTIONS
OptionDefinition
-gProduce debugging information.
The compiler suppor t s the use of -g with -O making it possibl e to debug opti-
mized code. The shortcuts taken by optimized code may occasionally produce surprising results:
• Some declared variables may not exist at all;
• Flow of control may briefly move unexpectedly;
• Some statements may not be executed because they com pu te constant
results or their values were already at hand;
• Some statements may execute in different places because they were
moved out of loops.
Nevertheless it proves possible to debug optimized output. This makes it
reasonable to use the optimizer for programs that might have bugs.
-QMakes the compiler print out each function name as it is compiled, and print
some statistics about each pass when it finishes.
DS52071B-page 70 2012 Microchip Technology Inc.
Compiler Command-Line Driver
TABLE 3-10:DEBUGGING OPTIONS (CONTINUED)
OptionDefinition
-save-temps Don’t delete intermedi ate fil es. Place them in the current di rec tory an d name
them based on the source file. Thus, compiling foo.c with -c
-save-temps would produce the following files:
foo.i(preprocessed file)
foo.p(pre procedure abstraction assembly language file)
foo.s(assembly language file)
foo.o(object file)
3.7.6Options for Controlling Optimization
The following options control compiler optimizations. Optimization levels available depend
on the compiler edition (see Chapter 15. “Optimizations”.)
TABLE 3-11:GENERAL OPTIMIZATION OPTIONS
OptionEditionDefinition
-O0AllDo not optimize. (This is the default.)
Without -O, the compiler’s goal is to reduce the cost of compilation
and to make debugging produce the expected results. Statements
are independent: if you sto p the pro gra m w ith a bre ak poi nt bet we en
statements, you can then assign a new value to any variable or
change the program counter to any other statement in the function
and get exactly the results you would expect from the source code.
The compiler only allocates variables declared register in registers.
-O
-O1
-O2STD, PRO Optimize even more. The compiler performs nearly all supported
-O3PROOptimize yet more. -O3 turns on all optimizations specified by -O2
AllOptimize. Optimizing compilation takes somewhat longer, and a lot
more host memory for a large function.
With -O, the compiler tries to reduce code size and execution time.
When -O is specified, the compiler turns on -fthread-jumps and
-fdefer-pop. The compiler turns on -fomit-frame-pointer.
optimizations that do not inv ol ve a space-speed trade-off. -O2 turns
on all optional optimizations except for loop unrolling (-fun-roll-loops), function inlining ( -finline-functions), and strict
aliasing optimizations (-fstrict-aliasing). It also turns on
Frame Pointer elimination (-fomit-frame-pointer). As compared to -O, this option increases both compilation time and the
performance of the generated code.
and also turns on the inline-functions option.
-OsPROOptimize for size. -Os enables all -O2 optimizations that do no t typi-
cally increase code size. It also performs further optimizations
designed to reduce code size.
The following options control specific optimizations. The -O2 option turns on all of
these optimizations except -funroll-loops, -funroll-all-loops and
-fstrict-aliasing.
2012 Microchip Technology Inc.DS52071B-page 71
MPLAB® XC16 C Compiler User’s Guide
Y ou can use the following flags in the rare cases when “fine-tuning” of optimizations to
be performed is desired.
TABLE 3-12:SPECIFIC OPTIMIZATION OPTIONS
OptionDefinition
-falign-functions
-falign-functions=n
-falign-labels
-falign-labels=n
-falign-loops
-falign-loops=n
-fcaller-savesEnabl e values to be allo cated in registe rs that will be cl obbered by
-fcse-follow-jumpsIn common subexpres sion elimination, sca n th rou gh jum p ins truc -
-fcse-skip-blocksThis is similar to -fcse-follow-jumps, but causes CSE to fol-
-fexpensive optimizations
-ffunction-sections
-fdata-sections
-fgcsePerform a global common subexpression elimination pass. This
Align the start of functions to the next power-of-two greater than
n, skipping up to n bytes. For instance,
-falign-functions=32 aligns functions to the next 32-byte
boundary, but -falign-functions=24 would align to the next
32-byte boundary onl y i f this ca n be don e by sk ipp ing 23 by tes or
less.
-fno-align-functions and -falign-functions=1 are
equivalent and mean that functions will not be aligned.
The assembler only supports this flag when n is a power of two;
so n is rounded up. If n is not spe cified, use a machi ne-dependent
default.
Align all branch targets to a power-of-two boundary, skipping up
to n bytes like -falign-functions. This option can easily
make code slower, because it must insert dummy operations for
when the branch target is reached in the usual flow of the code.
If -falign-loops or -falign-jumps are applicable and are
greater than this value, then their values are used instead.
If n is not specified, use a machine-dependent default which is
very likely to be 1, meani ng no alignment.
Align loops to a power-of-two boundary, skipping up to n bytes
like -falign-functions. The hope is that the loop will be executed many times, which will make up for any execution of the
dummy operations.
If n is not specified, use a machine-dependent default.
function calls, by emitting extra instructions to save and restore
the registers around suc h calls. Such alloc ation is done only when
it seems to result in better code than would otherwise be produced.
tions when the target of the jump is not reached by any other
path. For example, when CSE encounters an if statement with
an else clause, CSE will follow the jump when the condition
tested is false.
low jumps which conditionally skip over blocks. When CSE
encounters a simple if statement with no else clause,
-fcse-skip-blocks causes CSE to follow the jum p around the
body of the if.
Perform a number of minor optimizations that are relatively
expensive.
Place each function or data item into its own sec tio n in th e output
file. The name of the function or the name of the data item determines the section’ s name in the out put fil e.
Only use these options when there are significant benefits for
doing so. When you specify these options, the assembler and
linker may create larger object and executable files and will also
be slower.
pass also performs global constant and copy propagation.
-fgcse-lmWhen -fgcse-lm is enabled, global common subexpression
elimination will attempt to move loads which are only killed by
stores into themselv es. This allows a loop con taining a load/store
sequence to be changed to a load outside the loop, and a
copy/store within the loop.
-fgcse-smWhen -fgcse-sm is enabled, a store motion pass is run after
global common subexpression elimination. This pass will attempt
to move stores out of loops. When used in conjunction with
-fgcse-lm, loops containing a load/store sequence can be
changed to a load before the loop and a store after the loop.
-fno-defer-popAlways pop the arguments to each function call as soon as that
function returns. The compiler normally lets arguments accumulate on the stack for several function calls and pops them all at
once.
-fno-peephole
-fno-peephole2
-foptimize-
register-move
-fregmove
-frename-registersAttempt to avoid false dependencies in scheduled code by mak-
-frerun-cse-after-
loop
-frerun-loop-optRun the loop optimizer twice.
-fschedule-insnsAttempt to reorder instructions to eliminate dsPIC® DSC
-fschedule-insns2Similar to -fschedule-insns, but requests an additional pas s
-fstrength-reducePerform the optimizations of loop strength reduction and
Disable machine specific peephole optimizations. Peephole optimizations occur at various points during the compilation.
-fno-peephole disables peephole optimization on machine
instructions, while -fno-peephole2 disables high level peephole optimizatio ns . To disable peephole e nti rely, use both options.
Attempt to reassign r egi ste r num be rs i n m ov e in stru ctions and as
operands of other simple instructions in order to maximize the
amount of register tying.
-fregmove and -foptimize-register-moves are th e same
optimization.
ing use of registers left over after register allocation. This optimization will most benefit processors with lots of registers. It can,
however, make debugging impo ss ib le, si nce variables will no longer stay in a “home register”.
Rerun common subexpression elimination after loop
optimizations has been performed.
Read-After-Write stalls (see the “dsPIC30F Family Reference Manual” (DS70046) for more details). Typically improves
performance with no impact on code size.
of instruction scheduling after register allocation has been done.
-fstrict-aliasingAllows the compiler to assume the strictest aliasing rules applicable to the language being compiled. For C, this
activates optimizations based on the type of expressions. In particular, an object of one type is assumed never to reside at the
same address as an object of a different type, unless the types
are almost the same. For example, an unsigned int can alias
an int, but not a void* or a double. A character type may a lias
any other type.
Pay special attention to code like this:
union a_union {
int i;
double d;
};
int f() {
union a_union t;
t.d = 3.0;
return t.i;
}
The practice of reading from a different union member than the
one most recently written to (called “type-punning”) is common.
Even with -fstrict-aliasing, type-punning is allowed, provided the memory is accessed through the union type. So, the
code above will work as expected. However, this code might not:
int f() {
a_union t;
int* ip;
t.d = 3.0;
ip = &t.i;
return *ip;
}
-fthread-jumpsPerform optimizations where a check is made to see if a jump
branches to a location where another comparison subsumed by
the first is found. If so, the first branch is redirected to either the
destination of the second branch or a point immediately following
it, depending on whether the condition is known to be true or
false.
-funroll-loopsPerform the optimization of loop unrolling. This is only done for
loops whose number of iterations can be determined at compile
time or run time. -funroll-loops implies both
-fstrength-reduce and -frerun-cse-after-loop.
-funroll-all-loopsPerform the optimization of loop unrolling. This is done for all
loops and usually makes programs run more slowly.
-funroll-all-loops implies -fstrength-reduce, as well
as -frerun-cse-after-loop.
DS52071B-page 74 2012 Microchip Technology Inc.
Compiler Command-Line Driver
Options of the form -fflag specify machine-independent flags. Most flags have both
positive and negative forms; the negative form of -ffoo would be -fno-foo. In the
table below, only one of the forms is listed (the one that is not the default.)
-finline-functionsIntegrate all simple func tions into th eir calle rs. The comp iler
heuristically decides which functions are simple enough to
be worth integrating in this way. If all calls to a given function are integrated, and the function is declared static,
then the function is normally not output as assembler code
in its own right.
-finline-limit=n By default, the compiler limits the size of functions that can
be inlined. This flag allows the control of this limit for functions that are explicitly marked as inline (i.e., marked with
the inline keyword). n is the size of functions that can be
inlined in number of pseudo instructions (not counting
parameter handling). The default value of n is 10000.
Increasing this value can result in more inlined code at the
cost of compilation time and memory consumption.
Decreasing usually makes the compilation faster and less
code will be inlined (which presumably means slower
programs). This option is particularly useful for programs
that use inlining.
Note: Pseudo instruction represents, in this particular context, an abstract measurement of function’s size. In no way
does it represent a count of assembly instructions and as
such, its exact meaning might change from one release of
the compiler to an another.
-fkeep-inline-functions Even if all calls to a given function are integrated, and the
function is declared static, output a separate run time
callable version of the function. This switch does not affect
extern inline functions.
-fkeep-static-constsEmit variables declared static const when optimization isn’t
turned on, even if the variables aren’t referenced.
The compiler enables this option by default. If you want to
force the compiler to check if the variable was referenced,
regardless of whether or not optimization is turned on, use
the -fno-keep-static-consts option.
-fno-function-cseDo not put function addresses in registers; make each
instruction that calls a constant function contain the
function’s addres s exp lic itl y.
This option results in less efficient code, but some strange
hacks that alter the ass embler output may be confu sed by
the optimizations performed when this option is not used.
-fno-inlineDo not pay attention to the inline keyword. Normally this
option is used to keep the compiler from expanding any
functions inline. If optimization is not enabled, no functions
can be expanded inline.
-fomit-frame-pointerDo not keep the Frame Pointer in a register for functions
that don’t need one. Thi s avoids the inst ructions to sav e, set
up and restore Frame Pointers; it also makes an extra register available in many functions.
-foptimize-sib-
ling-calls
Optimize sibling and tail recursive calls.
2012 Microchip Technology Inc.DS52071B-page 75
MPLAB® XC16 C Compiler User’s Guide
3.7.7Options for Controlling the Preprocessor
The following options control the compiler preprocessor.
TABLE 3-14:PREPROCESSOR OPTIONS
OptionDefinition
-Aquestion (answer)Assert the answer answer for question question, in ca se it is
tested with a preprocessing conditional such as #if
#question(answer). -A- disables the standard assertions
that normally describe the target machine.
For example, the function prototype for main might be declared
as follows:
#if #environ(freestanding)
int main(void);
#else
int main(int argc, char *argv[]);
#endif
A -A command-line option could then be used to select
between the two prototypes. For example, to select the first of
the two, the following command-line option could be used:
-Aenviron(freestanding)
-A -predicate =answer Cancel an assertion with the p redi cate predicate and answer
answer.
-A predicate =answerMake an assertion with the predicate predicate and answer
answer. This form is preferred to the older form
-A predicate(answer), which is still supported, because it
does not use shell special characters.
-CTell the preprocessor not to discard comments. Used with the
-E option.
-dDTell the preprocessor to not remove macro definitions into the
output, in their proper sequence.
-DmacroDefine macro macro with the string 1 as its definition.
-Dmacro=defnDefine macro macro as defn. All instances of -D on the command line are processed before any -U options.
-dMTell the preprocessor to output only a list of the macro
definitions that are in effect at the end of preprocessing. Used
with the -E option.
-dNLike -dD except that the macro arguments and contents are
omitted. Only #define name is included in the output.
-fno-show-columnDo not print column numbers in diagnostics. This may be
necessary if diagnostics are being scanned by a program that
does not understand the column numbers, such as dejagnu.
-HPrint t he nam e o f e ac h h ead er fi le us ed, in addition to oth er n ormal activities.
DS52071B-page 76 2012 Microchip Technology Inc.
Compiler Command-Line Driver
TABLE 3-14:PREPROCESSOR OPTIONS (CONTINUED)
OptionDefinition
-I-Any directories you specify with -I options before the -I-
options are searched only for the case of #include "file";
they are not searched for #include <file>.
If additional directories are specified with -I options after the
-I-, these directories are searched for all #include
directives. (Ordinarily all -I directories are used this way.)
In addition, the -I- option inhibits the use of the current
directory (where the current input file came from) as the first
search directory for #include "file". There is no way to
override this effect of -I-. With -I. you can speci fy se ar c hin g
the directory that was current when the compiler was invoked.
That is not exactly the same as what the preprocessor does by
default, but it is often satisfactory.
-I- does not inhibit the use of the standard system directories
for header files. Thus, -I- and -nostdinc are independent.
-IdirAdd the directory dir to the head of the list of directories to be
searched for header files. This can be used to override a
system header file, substituting your own version, since these
directories are searched before the system header file
directories. If you use more than one -I option, the directories
are scanned in left-to-right order; the standard system
directories come after.
-idirafter dirAdd the directory dir to the second include path. The
directories on the second include path are searched when a
header file is not found in any of the directories in the main
include path (the one that -I adds to).
-imacros fileProcess file as input, discard ing the res ulting output, be fore pro-
cessing the regular input file. Because the output generated
from the file is discarded, the only effect of -imacros file is
to make the macros defined in file available for use in the main
input.
Any -D and -U options on the command line are always
processed before -imacros file, regardless of the order in
which they are written. All the -include and -imacros
options are processed in the order in which they are written.
-include fileProcess file as input before processing the regular input file. In
effect, the contents of file are compiled first. Any -D and -U
options on the command line are always processed before
-include file, rega rdless of the orde r in which they are writ-
ten. All the -include and -imacros op tio ns are processed in
the order in which they are written.
-iprefix prefixSpecify prefix as the prefix for subsequent -iwithprefix
options.
-isystem dirAdd a directory to the beginning of the second include path,
marking it as a system directory, so that it gets the same special
treatment as is applied to the standard system directories.
-iwithprefix dirAdd a directory to the second include path. The directory’s
name is made by concatenating prefix and dir, where prefix
was specified previously with -iprefix. If a prefix has not yet
been specified, the directory containing the installed passes of
the compiler is used as the default.
-iwithprefixbefore
dir
Add a directory to the main include path. The directory’s name
is made by concatenating prefix and dir, as in the case of
-iwithprefix.
2012 Microchip Technology Inc.DS52071B-page 77
MPLAB® XC16 C Compiler User’s Guide
TABLE 3-14:PREPROCESSOR OPTIONS (CONTINUED)
OptionDefinition
-MTell the preprocessor to output a rule suitable for make describ-
ing the dependencies of each object file. For each source file,
the preprocessor outputs one make-rule whose target is the
object file name for that source file and whose dependencies
are all the #include header files it uses. This rule may be a
single line or may be continued with \-newline if it is long. The
list of rules is printed on standard output instead of the preprocessed C program.
-M implies -E (see Section 3.7.2 “Options for Controlling the
Kind of Output”).
-MDLike -M but the dependency information is written to a file and
compilation contin ues . The file contai nin g th e dependency information is given the same name as the source file with a .d
extension.
-MF fileWhen us ed with -M or -MM, specifies a file in which to write the
dependencies. If no -MF switch is given, the preprocessor
sends the rules to the same place it would have sent
preprocessed output.
When used with the driver options, -MD or -MMD, -MF,
overrides the default dependency output file.
-MGTreat missi ng hea der file s as gen erated files and assume they
live in the same directory as the source file. If -MG is specified,
then either -M or -MM must also be specified. -MG is not
supported with -MD or -MMD.
-MMLike -M but the output mentions only the user header files
included with #include “file”. System header files included
with #include <file> are omitted.
-MMDLike -MD except mention only user header files, not system
header files.
-MPThis option instructs CPP to add a phony ta rget for ea ch dependency other than the main file, causing eac h to depend on nothing. These dummy rules work around errors make gives if you
remove header files without updating the make-file to match.
This is typical output:
test.o: test.c test.h
test.h:
-MQSame as -MT, but it quotes any characters which are special to
make.
-MQ '$(objpfx)foo.o' gives
foo.c
The default target is automatically quoted, as if it were given
with -MQ.
-MT targetChange the target of the rule emitted by dependency
generation. By default, CPP takes the name of the main input
file, incl uding any path, deletes any file suffix such as .c, and
appends the platform’s usual object suffix. The result is the
target.
An -MT option will set the target to be exactly the string you
specify. If you want mul tiple targets, you can specify them as a
single argument to -MT, or use multiple -MT options.
For example:
-MT '$(objpfx)foo.o' might give $(objpfx)foo.o:
foo.c
$$(objpfx)foo.o:
DS52071B-page 78 2012 Microchip Technology Inc.
Compiler Command-Line Driver
TABLE 3-14:PREPROCESSOR OPTIONS (CONTINUED)
OptionDefinition
-nostdincDo not search the standard system directories for header files.
Only the direct ories you ha ve s pecifi ed w ith -I options (and the
current directory, if appropriate) are searched. (See
Section 3.7.10 “Options for Directory Search”) for
information on -I.
By using both -nostdinc and -I-, the inclu de-file search path
can be limited to only those directories explicitly specified.
-PTell the preprocessor not to generate #line directives. Used
with the -E option (see Section 3.7.2 “Options for Controlling the Kind of Output”).
-trigraphsSupport ANSI C trigraphs. The -ansi option also has this
effect.
-UmacroUndefine macro macro. -U options are evaluated after all -D
options, but before any -include and -imacros options.
-undefDo not predefine any nonstandard macros (inclu din g
architecture flags).
3.7.8Options for Assembling
The following options control assembler operations. For more on available options, see
the MPLAB Assembler, Linker and Utilities for PIC24 MCUs and dsPIC DSCs User’s Guide (DS51317).
TABLE 3-15:ASSEMBLY OPTIONS
OptionDefinition
-Wa,optionPass option as an option to the assembler. If option contains
commas, it is split into multiple options at the commas.
For example, to generate an assembly list file, use -Wa,-a.
3.7.9Options for Linking
2012 Microchip Technology Inc.DS52071B-page 79
MPLAB® XC16 C Compiler User’s Guide
If any of the options -c, -S or -E are used, the linker is not run and object file names
should not be used as arguments. For more on available options, see the MPLAB
Assembler, Linker and Utilities for PIC24 MCUs and dsPIC DSCs User’s Guide
(DS51317).
TABLE 3-16:LINKING OPTIONS
OptionDefinition
--fill=optionsFill unused program memory. The format is:
address and end_address will spec ify the rang e of prog ram memor y
addresses to fill. If end_address is not pro vided the n the expression
will be written to the spec ific m emory loc ation a t addres s address. T he
optional literal value unused may be specified to indicate that all
unused memory will be filled. If non e of the lo cation parameters are provided, all unused memory will be filled. expression will describe how
to fill the specified memory. The following options are available:
A single value
xc16-ld --fill=0x12345678@unused
Range of values
xc16-ld --fill=1,2,3,4,097@0x9d000650:0x9d000750
An incrementing value
xc16-ld --fill=7+=911@unused
By default, the linker will fill using data that is instruction-word length.
For 16-bit devices, the default fill width is 24 bits. However, you may
specify the value wid th using [wn:], where n is the fill valu e's wid th and
n belongs to [1, 3].
Multiple fill optio ns ma y be s pecif ied on the comm and li ne; the lin ker wil l
always process fill options at specific locations first.
--gc-sectionsRemove dead functions from code at link time.
Support is for ELF projects only. In order to make the best use of this
feature, add the -ffunction-sections option to the compiler
command line.
-LdirAdd directo ry dir to the list of directories to be searched for libraries
specified by the command-line option -l.
-legacy-libcUse legacy include files and libraries (v3.24 and before).
The format of include file and libraries changed in v3.25 to match
HI-TECH C compiler format.
DS52071B-page 80 2012 Microchip Technology Inc.
Compiler Command-Line Driver
TABLE 3-16:LINKING OPTIONS (CONTINUED)
OptionDefinition
-llibrarySearch the library named library when linking.
The linker searches a standard list of directories for the library, which is
actually a file nam ed liblibrary.a. The linker then uses this file as if
it had been specified precisely by name.
It makes a difference where in the command you write this option; the
linker processes librarie s and obj ect file s in the order they are spec ified.
Thus, foo.o -lz bar.o sea rch es li brary z after file foo.o but before
bar.o. If bar.o refers to functions in libz.a, those functions may not
be loaded.
The directories searched include several standard system directories,
plus any that you specify with -L.
Normally the files found this way are library files (archive files whose
members are object file s). The linke r handles an arch ive file by sca nning
through it for members which define symbols that have so far been
referenced but not defined. But if the file that is found is an ordinary
object file, it is linked in the usual fashion. The only difference between
using an -l option (e.g., -lmylib) and specifying a file name (e.g.,
libmylib.a) is that -l searches several directories, as specified.
By default the linker is directed to search:
<install-path>\lib
for libraries specified with the -l option.
This behavior can be overridden using the environment variables
defined in Section 16.4 “Predefined Macro Names”.
-nodefaultlibsDo not use the standard syst em lib raries w hen li nking . Only the libr arie s
you specify will be pas sed to the linker. The compiler may generate ca lls
to memcmp, memset and memcpy. These entries are usua lly res olve d by
entries in the standard compiler libraries. These entry points should be
supplied through some other mechanism when this option is specified.
-nostdlibDo not use the standard system st artup files or librari es when linking. No
startup files and only the libraries you specify will be passed to the
linker. The compiler may generate calls to memcmp, memset and memcpy. These entries are usually resolved by entries in standard
compiler libraries. These entry points should be supplied through some
other mechanism when this option is specified.
-sRemove all symbol table and relocation information from the
executable.
-T scriptSpeci fy th e linker script file, script, to be us ed at link tim e. This opt ion
is translated into the equivalent -T linke r option.
-u symbolPretend symbol is undefined to force linking of library modules to
define the symbol. It is legitimate to use -u multiple times with different
symbols to force loading of additional library modules.
-Wl,optionPass option as an option to the linker. If option contains commas, it
is split into multiple options at the commas.
For example, to generate a map file, use
-Xlinker option Pass option as an option to the linker. You can use this to supply
system-specific linker options that the compiler does not know how to
recognize.
-W1, -Map=Project.map.
2012 Microchip Technology Inc.DS52071B-page 81
MPLAB® XC16 C Compiler User’s Guide
3.7.10Options for Directory Search
The following options specify to the compiler where to find directories and files to
search.
TABLE 3-17:DIRECTORY SEARCH OPTIONS
OptionDefinition
-specs=fileProcess file after the compiler read s in t he standard specs file, in
order to override the defaults that the xc16-gcc driver program
uses when determining what switches to pass to xc16-cc1, xc16-as, xc16-ld, etc. More than one -specs=file can be
specified on the command line, and they are processed in order,
from left to right.
3.7.11Options for Code Generation Conventions
Options of the form -fflag specify machine-independent flags. Most flags have both
positive and negative forms; the negative form of -ffoo would be -fno-foo. In the
table below, only one of the forms is listed (the one that is not the default.)
TABLE 3-18:CODE GENERATION CONVENTION OPTIONS
OptionDefinition
-fargument-alias
-fargument-noalias
-fargument-
noalias-global
-fcall-saved-regTreat the register named reg as an allocatable register save d by
-fcall-used-regTreat the register named reg as an allocatable register that is
-ffixed-regTreat the register named reg as a fixed register; generated code
-fno-identIgnore the #ident directive.
Specif y the poss ible relations hips among p arameters and b etween
parameters and global data.
-fargument-alias specifies that arguments (parameters) may
alias each other and may alias global storage.
-fargument-noalias specifies that arguments do not alias
each other, but may alias global storage.
-fargument-noalias-global specifies th at a r gum en t s do n ot
alias each other and do not alias global storage.
Each language will automatically use whatever option is required
by the language standard. You should not need to use these
options yourself.
functions. It may be allocated even for temporaries or variables
that live across a call. Functions compiled this way will save and
restore the register reg if they use it.
It is an error to used this flag with the Frame Pointer or Stack
Pointer. Use of this flag for other registers that have fixed pervasive roles in the machine’s execution model will produce disastrous results.
A different sort of disaster will result from the use of this flag for a
register in which function values may be returned.
This flag should be used consistently through all modules.
clobbered by function calls. It may be allocated for temporaries or
variables that do not live across a cal l. Functions com piled this wa y
will not save and restore the register reg.
It is an error to use this flag with the Frame Pointer or Stack
Pointer. Use of this flag for other registers that have fixed pervasive roles in the machine’s execution model will produce disastrous results.
This flag should be used consistently through all modules.
should never refer to it (except perhaps as a Stack Pointer, Frame
Pointer or in some other fixed role).
reg must be the name of a register, e.g., -ffixed-w3.
-fpack-structPack all structure members together without holes. Usually you
would not want to use this option, since it makes the code
sub-optimal, and t he offs ets o f struct ure membe rs won’t agree wit h
system libraries.
The dsPIC® DSC device requires that words be aligned on even
byte boundaries, so care must be taken when using the packed
attribute to avoid run time addressing errors.
-fpcc-struct-
return
-fno-short-doubleBy default, the c om pil er u ses a double type equivalent to float.
-fshort-enumsAllocate to an enum type only as many bytes as it needs for the
-fverbose-asm
-fno-verbose-asm
-fvolatileConsider all memory references through pointers to be volatile.
-fvolatile-globalConsider all memory references to external and global data items
-fvolatile-staticConsider all memory references to static data to be volatile.
Return short struct and union values in memory like longer
ones, rather than in registers. This convention is less efficient, but
it has the advantage of allowing capability between the 16-bit compiler compiled files and files compiled with other compilers.
Short structures and unions are those whose size and alignment
match that of an integer type.
This option makes double equivalent to long double. Mixing
this option across modules can have unexpected results if
modules share double data either directly through argument
passage or indirectly through shared buffer space. Libraries
provided with the product function with either switch setting.
declared range of possible values. Specifically, the enum type will
be equivalent to the smallest integer type which has enough room.
Put extra commenta ry informa tion in the generated assembly c ode
to make it more readable.
-fno-verbose-asm, the default, causes the extra information to
be omitted and is useful when comparing two assembler files.
to be volatile. The use of this switch has no effect on static data.
3.8MPLAB IDE TOOLSUITE EQUIVALENTS
For information on related compiler options in MPLAB IDE, see the MPLAB Assembler ,
Linker and Utilities for PIC24 MCUs and dsPIC DSCs User’s Guide (DS51317).
2012 Microchip Technology Inc.DS52071B-page 83
MPLAB® XC16 C Compiler User’s Guide
DS52071B-page 84 2012 Microchip Technology Inc.
Chapter 4. Device-Related Features
4.1INTRODUCTION
The MPLAB XC16 C Compiler provides some features that are purely device-related.
• Device Support
• Device Header Files
•Stack
• Configuration Bit Access
• Using SFRs in MCUs
• Bit-Reversed and Modulo Addressing
4.2DEVICE SUPPORT
As discussed in Chapter 1. “Compiler Overview”, the compiler supports all Microchip
16-bit devices; dsPIC30/33 digital signal controls (DSCs) and PIC24 microcontrollers
(MCUs).
To determine the device support for your version of the compiler, consult the release
notes file, README.html, in the installation folder. For MPLAB IDE users, select
Help>Release Notes
MPLAB® XC16 C COMPILER
USER’S GUIDE
.
4.3DEVICE HEADER FILES
One header file that is typically included in each C source file you will write is xc.h, a
generic header file that will include other device- and architecture-specific header files
when you build your project.
Inclusion of this file will allow access to SFRs via special variables, as well as macros
which allow special memory access or inclusion of special instructions.
Avoid including chip-specific header files into your code, as this will reduce portability.
However, device-specific compiler header files are stored in the support\family\h
directory for reference.
For information about assembly include files (*.inc), see the assembler
documentation.
4.3.1Register Definition Files
The processor header files described in Section 4.5 “Configuration Bit Access”
name all SFRs for each part, but they do not define the addresses of the SFRs. A separate set of device-specific linker script files, one per part, is distributed in the
support\family\gld directory. These linker script files define the SFR addresses.
To use one of these files, specify the linker command-line option:
-T p30fxxxx.gld
where xxxx corresponds to the device part number.
For example, assuming that there is a file named app2010.c that contains an appli-
cation for the dsPIC30F2010 part, then it may be compiled and linked using the
following command line:
The -o command-line option names the output executable file, and the -T option gives
the linker script name for the dsPIC30F2010 part. If p30f2010.gld is not found in the
current directory , the linker searches in its known library paths. The default search path
includes all locations of preinst alled libraries and linker scripts.
You should copy the appropriate linker script file (supplied with the compiler) into your
project directory before any project-specific modifications are made.
4.4STACK
The 16-bit devices use what is referred to in this user’s guide as a “software stack”. This
is the typical stack arrangement employed by most computers and is ordinary data
memory accessed by a push-and-pop type instruction and a stack pointer register. The
term “hardware stack” is used to describe the stack employed by Microchip 8-bit
devices, which is only used for storing function return addresses.
The 16-bit devices dedicate register W15 for use as a software Stack Pointer. All
processor stack operations, including function calls, interrupts and exceptions, use the
software stack. The stack grows upward, towards higher memory addresses.
The dsPIC DSC device also supports stack overflow detection. If the Stack Pointer
Limit register, SPLIM, is initialized, the device will test for overflow on all stack operations. If an overfl ow shoul d occ ur , the proc esso r will in itia te a st ack er ror ex cepti on. By
default, this will result in a processor Reset. Applications may also install a stack error
exception handler by defining an interrupt function named _StackError. See Chap-ter 11. “Interrupts” for details.
The C run-time startup module initializes the Stack Pointer (W15) and the Stack Pointer
Limit register during the startup and initialization sequence. The initial values are
normally provided by the linker, which allocates the largest stack possible from unused
data memory. The location of the stack is reported in the link map output file.
Applications can ensure that at least a minimum-sized stack is available with the
--stack linker command-line option. See the MPLAB Assembl er, Linker and Utilities
for PIC24 MCUs and dsPIC DSCs User’s Guide (DS51317) for details.
Alternatively, a stack of specific size may be allocated with a user-defined section from
an assembly source file. In the following example, 0x100 bytes of data memory are
reserved for the stack:
.section *,data,stack
.space 0x100
The linker will allocate an appropriately sized section and initialize __SP_init and
__SPLIM_init so that the run-time startup code can properly initialize the stack. Note
that since this is a normal assembly code section, attributes such as address may be
used to further define the stack. Please see the MPLAB Assembler, Linker and Utilities for PIC24 MCUs and dsPIC DSCs User’s Guide (DS51317) for more information.
4.5CONFIGURATION BIT ACCESS
Microchip devices have several locations which contain the configuration bits or fuses.
These bits specify fundamental device operation, such as the oscillator mode, watchdog timer, programming mode and code protection. Failure to correctly set these bits
may result in code failure or a non-running device.
Configuration settings macros are provided that can be used to set configuration bits.
For details, see Appendix G. “XC16 Configuration Settings”.
DS52071B-page 86 2012 Microchip Technology Inc.
4.6USING SFRS
The Special Function Registers (SFRs) are registers which control aspects of the MCU
operation or that of peripheral modules on the device. These registers are device memory mapped, which means that they appear at, and can be accessed using, specific
addresses in the device’s data memory space. Individual bits within some registers
control independent features. Some registers are read-only; some are write-only . See
your device data sheet for more information.
Memory-mapped SFRs are accessed by special C variables that are placed at the
address of the r egister. These vari ab le s ca n be ac ce sse d like an y or di na ry C var ia b le
so that no special syntax is required to access SFRs.
The SFR variable identifiers are predefined in header files and are accessible once you
have included the <xc.h> header file (see Section 4.3 “Device Header Files”) into
your source code. Structures with bit-fields are also defined so you may access bits
within a register in your source code.
A linker script file for the appropriate device must be linked into your project to ensure
the SFR variable identifiers are linked to the correct address. MPLAB IDE will link in a
default linker script, but a linker script file must be explicitly specified if you are driving
the command-line toolchain. Linker scripts have a .gld extension (e.g.
p30F6014.gld) and basic files are provided with the compiler.
The convention in the processor header files is that each SFR is named, using the
same name that appears in the data sheet for the part – for example, CORCON for the
Core Control register. If the register has individual bits that might be of interest, then
there will also be a structure defined for that SFR, and the name of the structure will be
the same as the SFR name, with “bits” appended. For example, CORCONbits for the
Core Control register. The individual bits (or bit fields) are named in the structure using
the names in the data sheet – for example PSV for the PSV bit of the CORCON
register.
Here is the complete definition of CORCON (subject to change):
/* CORCON: CPU Mode control Register */
extern volatile unsigned int CORCON
typedef struct tagCORCONBITS {
unsigned IF :1; /* Integer/Fractional mode */
unsigned RND :1; /* Rounding mode */
unsigned PSV :1; /* Program Space Visibility enable */
unsigned IPL3 :1;
unsigned ACCSAT :1; /* Acc saturation mode */
unsigned SATDW :1; /* Data space write saturation enable */
unsigned SATB :1; /* Acc B saturation enable */
unsigned SATA :1; /* Acc A saturation enable */
unsigned DL :3; /* DO loop nesting level status */
unsigned :4;
} CORCONBITS;
extern volatile CORCONBITS CORCONbits __attribute__((__sfr__));
Device-Related Features
__attribute__((__sfr__));
Note: The symbols CORCON and CORCONbits refer to the same register and will
resolve to the same address at link time.
See MPLAB Assembler, Linker and Utilities for PIC24 MCUs and dsPIC DSCs User’s Guide (DS51317) for more information on using linker scripts.
For example, the following is a sample real-time clock. It uses an SFR, e.g. TMR1, as
well as bits within an SFR, e.g. T1CONbits.TCS. Descriptions for these SFRs are
found in the p30F6014.h file (this file will automatically be included by <xc.h> so you
do not need to include this into your source code). This file would be linked with the
device specific linker script which is p30F6014.gld.
2012 Microchip Technology Inc.DS52071B-page 87
MPLAB® XC16 C Compiler User’s Guide
EXAMPLE 4-1: SAMPLE REAL-TIME CLOCK
/*
** Sample Real Time Clock for dsPIC
**
** Uses Timer1, TCY clock timer mode
** and interrupt on period match
*/
#include <xc.h>
/* Timer1 period for 1 ms with FOSC = 20 MHz */
#define TMR1_PERIOD 0x1388
struct clockType
{
unsigned int timer; /* countdown timer, milliseconds */
unsigned int ticks; /* absolute time, milliseconds */
unsigned int seconds; /* absolute time, seconds */
} volatile RTclock;
if (RTclock.timer > 0) /* if countdown timer is active */
RTclock.timer -= 1; /* decrement it */
RTclock.ticks++; /* increment ticks counter */
if (sticks++ > 1000)
{ /* if time to rollover */
sticks = 0; /* clear seconds ticks */
RTclock.seconds++; /* and increment seconds */
}
IFS0bits.T1IF = 0; /* clear interrupt flag */
return;
}
DS52071B-page 88 2012 Microchip Technology Inc.
Device-Related Features
4.7BIT-REVERSED AND MODULO ADDRESSING
Bit-reversed and modulo addressing is supported on all dsPIC devices.
Bit-reversed addressing is used for simplifying and speeding-up the writes to X-space
data arrays in FFT (Fast Fourier Transform) algorithms. When enabled, pre-increment
or post-increment addressing modes will reverse the lower order address bits used by
instructions.
Modulo, or circular, addressing provides an automated means to support circular data
buffers using the dsPIC hardware. When used, software no longer needs to perform
data address boundary checks on arrays.
The compiler does not directly support the use of bit-reversed and modulo addressing;
that is, it cannot generate code from C source that assumes these addressing modes
are enabled when accessing memory. If either of these addressing modes are set up
on the target device, then it is the programmer’s responsibility to ensure that the compiler does not use those registers that are specified to use either modulo or bit-reversed
addressing as pointers. Particular care must be exercised if interrupts can occur while
one of these addressing modes is enabled.
It is possible to define arrays in C that will be suitably aligned in memory for modulo
addressing by hand-written assembly language functions. The aligned attribute may
be used to define arrays that are positioned for use as incrementing modulo buffers.
Initialization of the start and end addresses, as well as the registers that modulo
address is applied must be written by hand to match the array specification. The
reverse attribute may be used to define arrays that are positioned for use as decrementing modulo buffers. For more information on these attributes, see
Section 10.2.1 “Function Specifiers”. For more information on bit-reversed or modulo addressing, see Chapter 3 of the “dsPIC30F Family Reference Manual” (DS70046).
2012 Microchip Technology Inc.DS52071B-page 89
MPLAB® XC16 C Compiler User’s Guide
NOTES:
DS52071B-page 90 2012 Microchip Technology Inc.
MPLAB® XC16 C COMPILER
USER’S GUIDE
Chapter 5. Differences Between MPLAB XC16 and ANSI C
This compiler conforms to the ANS X3.159-1989 Standard for programming languages.
This is commonly called the C89 Standard. It is referred to as the ANSI C Standard in
this manual. Some features from the later standard C99 are also supported.
• Divergence from the ANSI C Standard
• Extensions to the ANSI C Standard
• Implementation-Defined Behavior
5.1DIVERGENCE FROM THE ANSI C STANDARD
There are no divergences from the ANSI C standard.
5.2EXTENSIONS TO THE ANSI C STANDARD
The MPLAB XC16 C Compiler provides extensions to the ANSI C standard in these
areas: keywords and expressions.
5.2.1Keyword Differences
The new keywords are part of the base GCC implementation and the discussions in the
referenced sections are based on the standard GCC documentation, tailored for the
specific syntax and semantics of the 16-bit compiler port of GCC.
• Specifying Attributes of Variables – Section 6.11 “Variable Attributes”
• Specifying Attributes of Functions – Section 10.2.1 “Function Specifiers”
Certain features of the ANSI C standard have implementation-defined behavior. This
means that the exact behavior of some C code can vary from compiler to compiler.
The exact behavior of the MPLAB XC16 C Compiler is detailed throughout this
documentation, and is fully summarized in Appendix A. “Implementation-Defined Behavior”.
2012 Microchip Technology Inc.DS52071B-page 91
MPLAB® XC16 C Compiler User’s Guide
NOTES:
DS52071B-page 92 2012 Microchip Technology Inc.
Chapter 6. Supported Data Ty pe s and Variables
6.1INTRODUCTION
The MPLAB XC16 C Compiler supports a variety of data types and qualifiers (attributes). These data types and variables are discussed here. For information on where
variables are stored in memory, see Chapter 7. “Memory Allocation and Access”.
• Identifiers
• Integer Data Types
• Floating-Point Data Types
• Structures and Unions
• Pointer Types
• Complex Data Types
• Literal Constant Types and Formats
• Standard Type Qualifiers
• Compiler-Specific type Qualifiers
• Variable Attributes
MPLAB® XC16 C COMPILER
USER’S GUIDE
6.2IDENTIFIERS
A C variable identifier (as well as a function identifier) is a sequence of letters and digits
where the underscore character, “_”, counts as a letter. Identifiers cannot start with a
digit. Although they may start with an underscore, such identifiers are reserved for the
compiler’s use and should not be defined by your programs. Such is not the case for
assembly domain identifiers, which often begin with an underscore, see the MPLAB
Assembler, Linker and Utilities for PIC24 MCUs and dsPIC DSCs User’s Guide
(DS51317).
Identifiers are case sensiti ve , so main is different from Main.
All characters are significant in an identifier, although identifiers longer than 31
characters in length are less portable.
2012 Microchip Technology Inc.DS52071B-page 93
MPLAB® XC16 C Compiler User’s Guide
6.3INTEGER DATA TYPES
Table 6-1 shows integer data types that are supported in the compiler. All unspecified
or signed integer data types are arithmetic type signed integer. All unsigned integer
data types are arithmetic type unsigned integer.
TABLE 6-1:INTEGER DATA TYPES
TypeBitsMinMax
char, signed char8-128127
unsigned char80255
short, signed short16-3276832767
unsigned short16065535
int, signed int16-3276832767
unsigned int16065535
long, signed long32-2
unsigned long3202
long long*, signed long long*64-2
unsigned long long*6402
* ANSI-89 extension
31
63
231 - 1
32
- 1
263 - 1
64
- 1
There is no type for storing single bit quantiti es.
All integer values are specified in little endian format, which means:
• The least significant byte (LSB) is stored at the lowest address
• The least significant bit (LSb) is stored at the lowest-numbered bit position
As an example, the long value of 0x12345678 is stored at address 0x100 as follows:
0x1000x1010x1020X103
0x780x560x340x12
As another example, the long value of 0x12345678 is stored in registers w4 and w5:
w4w5
0x56780x1234
Signed values are stored as a two’s complement integer value.
Preprocessor macros that specify integer minimum and maximum values are available
after including <limits.h> in your source code, located by default in:
<install directory>\include
As the size of data types is not fully specified by the ANSI Standard, these macros allow
for more portable code which can check the limits of the range of values held by the
type on this implementation.
For information on implementation-defined behavior of integers, see
Section A.6 “Integers”.
6.3.1Double-Word Integers
The compiler supports data types for integers that are twice as long as long int.
Simply write long long int for a signed integer, or unsigned long long int
for an unsigned integer. To make an integer constant of type long long int, add the
suffix LL to the integer. To make an integer constant of type unsigned long long int, add the suffix ULL to the integer.
You can use these types in arithmetic like any other integer types.
DS52071B-page 94 2012 Microchip Technology Inc.
Supported Data Types and Variables
6.3.2char Types
The compiler supports data types for char, which defaults to signed char. An option
can be used to use unsigned char as the defaul t, see Section 3.7.3 “Options for Controlling the C Dialect”.
It is a common misconception that the C char types are intended purely for ASCII character manipulation. This is not true; indeed, the C language makes no guarantee that
the default character representation is even ASCII (however, this implementation does
use ASCII as the character representation). The char types are simp ly the s malle st of
the multi-bit integer sizes, and behave in all respects like integers. The reason for the
name “char” is historical and does not mean that char can only be used to represent
characters. It is possible to freely mix char values with values of other types in C
expressions. With the MPLAB XC16 C Compiler, the char types will commonly be
used for a number of purposes: as 8-bit integers, as storage for ASCII characters, and
for access to I/O locations.
6.4FLOATING-POINT DATA TYPES
The compiler uses the IEEE-754 format. Table 6-2 shows floating point data types that
are supported. All floating point data types are arithmetic type real.
TABLE 6-2:FLOATING POINT DATA TYPES
TypeBitsE MinE MaxN MinN Max
float32-1261272
double*32-1261272
long double64-102210232
E = Exponent
N = Normalized (approximate)
* double is equivalent to long double if -fno-short-double is used.
-126
-126
-1022
2
2
2
128
128
1024
All floating point values are specified in little endian format, which means:
• The least significant byte is stored at the lowest address
• The least significant bit is stored at the lowest-numbered bit position
As an example, the double value of 1.2345678 is stored at address 0x100 as follows:
0x1000x1010x1020X103
0x510x060x9E0x3F
As another example, the long value of 1.2345678 is stored in registers w4 and w5:
w4w5
0x06510x3F9E
Floating-point types are always signed and the unsigned keyword is illegal when
specifying a floating-point type.
Preprocessor macros that specify valid ranges are available after including
<float.h> in your source code
.
For information on implementation-defined behavior of floating point numbers, see
section Section A.7 “Floating Point”.
2012 Microchip Technology Inc.DS52071B-page 95
MPLAB® XC16 C Compiler User’s Guide
6.5STRUCTURES AND UNIONS
MPLAB XC16 C Compiler supports struct and union types. Structures and union s
only differ in the memory offset applied to each member.
These types will be at least 1 byte wide. Bit-fields are fully supported in structures.
Structures and unions may be passed freely as function arguments and function return
values. Pointers to structures and unions are fully supported.
Implementation-defined behavior of structures, unions and bit-fields is described in
Section A.10 “Structures, Unions, Enumerations and Bit Fields”.
6.5.1Structure and Union Qualifiers
The MPLAB XC16 C Compiler supports the use of type qualifiers on structures. When
a qualifier is applied to a structure, all of its members will inherit this qualification. In the
following example, the structure is qualified const.
const struct foo {
int number;
int *ptr;
} record = { 0x55, &i };
In this case, the entire structure may be placed into the program space where each
member will be read-only. Remember that all members are usually initialized if a
structure is const as they cannot be initialized at runtime.
If the members of the structure were individually qualified const, but the structure was
not, then the structure would be positioned into RAM, but each member would be still
be read-only. Compare the following structure with the one above.
struct {
const int number;
int * const ptr;
} record = { 0x55, &i};
6.5.2Bit-Fields in Structures
The MPLAB XC16 C Compiler fully supports bit-fields in structures.
Bit-fields are, by default, signed int. They may be made an unsigned int bit field
by using a command line option, see Section 3.7.3 “Options for Controlling the C Dialect”.
The first bit defined will be the LSb of the word in which it will be stored.
The compiler supports bit fields with any bit size, up to the size of t he underlying type.
Any integral type can be made into a bit field. The allocation does not normally cross a
bit boundary natural to the underlying type.
For example:
struct foo {
long long i:40;
int j:16;
char k:8;
} x;
struct bar {
long long I:40;
char J:8;
int K:16;
} y;
DS52071B-page 96 2012 Microchip Technology Inc.
Supported Data Types and Variables
struct foo will have a size of 10 bytes using the c ompiler. i will be allocated at bit
offset 0 (through 39). There will be 8 bits of padding before j, allocated at bit offset 48.
If j were allocated at the next available bit offset, 40, it would cross a storage boundary
for a 16 bit integer. k will be allocated after j, at bit offset 64. The structure will contain
8 bits of padding at the end to maintain the required alignment in the case of an array.
The alignment is 2 bytes because the largest alignment in the structure is 2 bytes.
struct bar will have a size of 8 bytes using the compiler. I will be allocated at bit
offset 0 (through 39). There is no need to pad before J because it will not cross a
storage boundary for a char. J is allocated at bit offset 40. K can be allocated starting
at bit offset 48, completing the structure without wasting any space.
Unnamed bit-fields may be declared to pad out unused space between active bits in
control registers. For example:
struct foo {
unsigned lo : 1;
unsigned : 6;
unsigned hi : 1;
} x;
A structure with bit-fields may be initialized by supplying a comma-separated list of initial values for each field. For example:
struct foo {
unsigned lo : 1;
unsigned mid : 6;
unsigned hi : 1;
} x = {1, 8, 0};
Structures with unnamed bit fields may be initialized. No initial value should be supplied
for the unnamed members, for example:
struct foo {
unsigned lo : 1;
unsigned : 6;
unsigned hi : 1;
} x = {1, 0};
will initialize the members lo and hi correctly.
2012 Microchip Technology Inc.DS52071B-page 97
MPLAB® XC16 C Compiler User’s Guide
6.6POINTER TYPES
There are two basic pointer types supported by the MPLAB XC16 C Compiler: data
pointers and function pointers. Data pointers hold the addresses of variables which can
be indirectly read, and possibly indirectly written, by the program. Function pointers
hold the address of an executable function which can be called indirectly via the pointer.
6.6.1Combining Type Qualifiers and Pointers
It is helpful to first review the ANSI C standard conventions for definitions of pointer
types.
Pointers can be qualified like any other C object, but care must be taken when doing
so as there are two quantities associated with pointers. The first is the actual pointer
itself, which is treated like any ordinary C variable and has memory reserved for it. The
second is the target, or targets, that the pointer references, or to which the pointer
points. The general form of a pointer definition looks like the following:
Any qualifiers to the right of the * (i.e., next to the pointer’s name) relate to the pointer
variable itself. The type and any qualifiers to the left of the * relate to the pointer’s targets. This makes sense since it is also the * operator that dereferences a pointer, which
allows you to get from the pointer variable to its current target.
Here are three examples of pointer definitions using the volatile qualifier. The fields
in the definitions have been highlighted with spacing:
volatile int * vip ;
int * volatile ivp ;
volatile int * volatile vivp ;
The first example is a pointer called vip. It contains the address of int objects that
are qualified volatile. The pointer itself – the variable that holds the address – is not volatile; however, the objects that are accessed when the pointer is dereferenced
are treated as being volatile. In other words, the target objects accessible via the
pointer may be externally modified.
The second example is a pointer called ivp which also contains the address of int
objects. In this example, the pointer itself is volatile, that is, the address the pointer
contains may be externally modified; however, the objects that can be accessed when
dereferencing the pointer are not volatile.
The last example is of a pointer called vivp which is itself qualified volatile, and
which also holds the address of volatile objects.
Bear in mind that one pointer can be assigned the addresses of many objects; for
example, a pointer that is a parameter to a function is assigned a new object address
every time the function is called. The definition of the pointer must be valid for every
target address assigned.
Note: Care must be taken when describing pointers. Is a “const pointer” a pointer
that points to const objects, or a poi nter t hat is const itself? You can talk
about “pointers to const” and “const pointers” to help clarify the definition,
but such terms may not be universally understood.
DS52071B-page 98 2012 Microchip Technology Inc.
Supported Data Types and Variables
6.6.2Data Pointers
All standard data pointers are 16 bits wide. This is sufficient to access the full data
memory space.
These pointers are also able to access const-qualified objects, although in the program memory space, const-qualified objects appear in a unique memory range in the
data space using the PSV window. In this case, the -mconst-in-data option should
not be in force (see Section 3.7.1 “Options Specific to 16-Bit Devices”.)
Pointers which access the managed PSV space are 32-bits wide. The extra space
allows these pointers to access any PSV page.
A set of special purpose, 32-bit data pointers are also available. See Chapter
7. “Memory Allocation and Acce ss” for more information.
6.6.3Function Pointers
The MPLAB XC16 C Compiler fully supports pointers to functions, which allows functions to be called indirectly. Function pointers are always 16 bits wide.
In the small code model (up to 32 kWords of code), 16-bit wide function pointers can
access any function location. In the large code model, which supports more than 32
kWords of code, pointers hold the address of a GOTO instruction in a lookup table.
These instructions are able to reach any memory location, but the lookup table itself is
located in the lower program memory, thus allowing the pointers themselves to remain
as 16-bit wide variables.
As function pointers are only 16-bits wide, these pointers cannot point beyond the first
64K of FLASH. Should the address of a function that is allocated beyond the first 64K
of FLASH be taken, the linker will arrange for a handle section to be generated. The
handle section will always be allocated within the first 64K. Each handle provides a
level of indirection which allows 16-bit pointers to access the full range of FLASH. This
operation may be disable with the --no-handles linker opti o n .
6.6.4Special Pointer Targets
Pointers and integers are not interchangeable. Assigning an integer value to a pointer
will generate a warning to this effect. For example:
const char * cp = 0x123; // the compiler will flag this as bad code
There is no information in the integer, 0x123, relating to the type, size or memory location of the destination. Avoid assigning an integer (whether it be a constant or variable)
to a pointer at all times. Addresses assigned to pointers should be derived from the
address operator “
In instances where you need to have a pointer reference a seemingly arbitrary address
or address range, consider defining an object or label at the desired location. If the
object is defined in assembly code, use a C declaration (using the extern keyword)
to create a C object which links in with the external object and whose address can be
taken.
&“ that C provides.
2012 Microchip Technology Inc.DS52071B-page 99
MPLAB® XC16 C Compiler User’s Guide
Take care when comparing (subtracting) pointers. For example:
if(cp1 == cp2)
; take appropriate action
The ANSI C standard only allows pointer comparisons when the two pointer targets are
the same object. The address may extend to one element past the end of an array.
Comparisons of pointers to integer constants are even more risky, for example:
if(cp1 == 0x246)
; take appropriate action
A NULL pointer is the one instance where a constant value can be safely assigned to a
pointer. A NULL pointer is numerically equal to 0 (zero), but since they do not guarantee
to point to any valid object and should not be dereferenced, this is a special case
imposed by the ANSI C standard. Comparisons with the macro NULL are also allowed.
6.7COMPLEX DATA TYPES
The compiler supports complex data types. You can declare both complex integer
types and complex floating types, using the keyword __complex__.
For example, __complex__ float x; declares x as a variable whose real part and
imaginary part are both of type float. __complex__ short int y; declares y to
have real and imaginary parts of type short int.
To write a constant with a complex data type, use the suffix ‘i’ or ‘j’ (either one; they
are equivalent). For example, 2.5fi has type __complex__ float and 3i has type
__complex__ int. Such a constant is a purely imaginary value, but you can form
any complex value you like by adding one to a real constant.
To extract the real part of a complex-valued expression exp, write __real__ exp.
Similarly, use _ _imag__ to extract the imaginary part. For example;
__complex__ float z;
float r;
float i;
r =
i =
__real__ z;
__imag__ z;
The operator, ~, performs complex conjugation when used on a value with a complex
type.
The compiler can allocate complex automatic variables in a noncontiguous fashion; it’s
even possible for the real part to be in a register while the imaginary part is on the stack
(or vice-versa). The debugging information format has no way to represent noncontiguous allocations like these, so the compiler describes noncontiguous complex
variables as two separate variables of noncomplex type. If the variable’s actual name
is foo, the two fictitious variables are named foo$real and foo$imag.
DS52071B-page 100 2012 Microchip Technology Inc.
Loading...
+ hidden pages
You need points to download manuals.
1 point = 1 manual.
You can buy points or you can get point for every manual you upload.