IAR C language extensions
The compiler provides a wide set of C language extensions. To help you to find the extensions required by your application, they are grouped like this in this section:
Extensions for embedded systems programming—extensions specifically tailored for efficient embedded programming for the specific microcontroller you are using, typically to meet memory restrictions
Relaxations to Standard C—that is, the relaxation of some minor Standard C issues and also some useful but minor syntax extensions, see Relaxations to Standard C.
Extensions for embedded systems programming
The following language extensions are available both in the C and the C++ programming languages and they are well suited for embedded systems programming:
Memory attributes, type attributes, and object attributes
For information about the related concepts, the general syntax rules, and for reference information, see Extended keywords.
Placement at an absolute address or in a named section
The
@operator or the directive#pragmalocationcan be used for placing global and static variables at absolute addresses, or placing a variable or function in a named section. For more information about using these features, see Controlling data and function placement in memory, and location.Alignment control
Each data type has its own alignment. For more information, see Alignment. If you want to change the alignment, the
__packeddata type attribute, the#pragma packdirective and the#pragma data_alignmentdirective are available. If you want to check the alignment of an object, use the__ALIGNOF__()operator.The
__ALIGNOF__operator is used for accessing the alignment of an object. It takes one of two forms:__ALIGNOF__(type)__ALIGNOF__(expression)
In the second form, the expression is not evaluated.
See also the Standard C file
stdalign.h.Bitfields and non-standard types
In Standard C, a bitfield must be of the type
intorunsigned int. Using IAR C language extensions, any integer type or enumeration can be used. The advantage is that the struct will sometimes be smaller. For more information, see Bitfields.
Dedicated section operators
The compiler supports getting the start address, end address, and size for a section with these built-in section operators:
| Returns the address of the first byte of the named section or block. |
| Returns the address of the first byte after the named section or block. |
| Returns the size of the named section or block in bytes. |
The operators can be used on named sections or on named blocks defined in the linker configuration file.
These operators behave syntactically as if declared like:
void * __section_begin(char const *section) void * __section_end(char const *section) size_t __section_size(char const *section)
When you use the @ operator or the #pragma location directive to place a data object or a function in a user-defined section, or when you use named blocks in the linker configuration file, the section operators can be used for getting the start and end address of the memory range where the sections or blocks were placed.
The named section must be a string literal and it must have been declared earlier with the #pragmasection directive. If the section was declared with a memory attribute memattr, the type of the __section_begin operator is a pointer to memattrvoid. Otherwise, the type is a default pointer to void. Note that you must enable language extensions to use these operators.
The operators are implemented in terms of symbols with dedicated names, and will appear in the linker map file under these names:
Operator | Symbol |
|---|---|
|
|
|
|
|
|
Note
The linker will not necessarily place sections with the same name consecutively when these operators are not used. Using one of these operators (or the equivalent symbols) will cause the linker to behave as if the sections were in a named block. This is to assure that the sections are placed consecutively, so that the operators can be assigned meaningful values. If this is in conflict with the section placement as specified in the linker configuration file, the linker will issue an error.
Example
In this example, the type of the __section_begin operator is void __near*.
#pragmasection="MYSECTION"__near ...section_start_address = __section_begin("MYSECTION");
Relaxations to Standard C
This section lists and briefly describes the relaxation of some Standard C issues and also some useful but minor syntax extensions:
An array can have an incomplete
struct,union, orenumtype as its element type. The types must be completed before the array is used (if it is), or by the end of the compilation unit (if it is not).A zero-length array as the last member of a structure has similar behavior as the ISO C99 flexible array member. This is an extension found in the GNU C compiler.
Structures with flexible array members
A structure with a flexible array member can appear as a member of another structure or as an array element. This is an extension found in the GNU C compiler.
Forward declaration of
enumtypesThe extensions allow you to first declare the name of an
enumand later resolve it by specifying the brace-enclosed list.Accepting missing semicolon at the end of a
structorunionspecifierA warning—instead of an error—is issued if the semicolon at the end of a
structorunionspecifier is missing.Null and
voidIn operations on pointers, a pointer to
voidis always implicitly converted to another type if necessary, and a null pointer constant is always implicitly converted to a null pointer of the right type if necessary. In Standard C, some operators allow this kind of behavior, while others do not allow it.Casting pointers to integers in static initializers
In an initializer, a pointer constant value can be cast to an integral type if the integral type is large enough to contain it. For more information about casting pointers, see Casting.
Taking the address of a register variable
In Standard C, it is illegal to take the address of a variable specified as a register variable. The compiler allows this, but a warning is issued.
long floatmeansdoubleDigit separators for integer literals (
1'000'000) are supported.Redeclarations of
typedefthat occur in the same scope are allowed, but a warning is issued.Assignment and pointer difference is allowed between pointers to types that are interchangeable but not identical, for example,
unsigned char *andchar *. This includes pointers to integral types of the same size. A warning is issued.Assignment of a string constant to a pointer to any kind of character is allowed, and no warning is issued.
A non-
lvaluearray expression is converted to a pointer to the first element of the array when it is used.Comments at the end of preprocessor directives
This extension, which makes it legal to place text after preprocessor directives, is enabled unless the strict Standard C mode is used. The purpose of this language extension is to support compilation of legacy code—we do not recommend that you write new code in this fashion.
An extra comma at the end of
enumlistsPlacing an extra comma is allowed at the end of an
enumlist. In strict Standard C mode, a warning is issued.A label preceding a
}In Standard C, a label must be followed by at least one statement. Therefore, it is illegal to place the label at the end of a block. The compiler allows this, but issues a warning. Note that this also applies to the labels of
switchstatements.An empty declaration (a semicolon by itself) is allowed, but a remark is issued (provided that remarks are enabled).
Standard C requires that all initializer expressions of static arrays, structs, and unions are enclosed in braces.
Single-value initializers are allowed to appear without braces, but a warning is issued. The compiler accepts this expression:
struct str { int a; } x = 10;Declarations in other scopes
External and static declarations in other scopes are visible. In the following example, the variable
ycan be used at the end of the function, even though it should only be visible in the body of theifstatement. A warning is issued.int test(int x) { if (x) { extern int y; y = 1; } return y; }Static functions in function and block scopes
Static functions may be declared in function and block scopes. Their declarations are moved to the file scope.
Numbers scanned according to the syntax for numbers
Numbers are scanned according to the syntax for numbers rather than the
pp-numbersyntax. Therefore,0x123e+1is scanned as three tokens instead of one valid token. (If the‑‑strictoption is used, thepp-numbersyntax is used instead.)A translation unit (input file) might be empty of declarations.
Assignment of pointer types is allowed in cases where the destination type has added type qualifiers that are not at the top level, for example,
int **toconst int **. Comparisons and pointer difference of such pairs of pointer types are also allowed. A warning is issued.Pointers to different function types
Pointers to different function types might be assigned or compared for equality (
==) or inequality (!=) without an explicit type cast. A warning is issued. This extension is not allowed in C++ mode.Assembler statements are accepted. This is disabled in strict C mode because it conflicts with the C standard for a call to the implicitly declared
asmfunction.The non-standard preprocessing directive
#include_nextis supported. This is a variant of the#includedirective. It searches for the named file only in the directories on the search path that follow the directory in which the current source file (the one containing the#include_nextdirective) is found. This is an extension found in the GNU C compiler.The non-standard preprocessing directive
#warningis supported. It is similar to the#errordirective, but results in a warning instead of a catastrophic error when processed. This directive is not recognized in strict mode. This is an extension found in the GNU C compiler.Mixed string concatenations are accepted.
wchar_t * str="a" L "b";
GNU style statement expressions (a sequence of statements enclosed by braces) are accepted.
GNU style case ranges are accepted (
case 1 ... 5:). Note the extra space characters around....GNU style designated initializer ranges are accepted. Note the extra space characters around
....Example:
int widths[] = {[0 ... 9] = 1, [10 ... 99] = 2, [100] = 3};The non-standard operator
typeofis supported when IAR extensions are enabled, as a way of referring to the type of an expression. The syntax is like that ofsizeof, but it behaves semantically like a type name defined withtypedef. This is an extension found in the GNU C compiler.The non-standard keyword
__auto_typeis supported when IAR extensions are enabled. Declaring a variable with the__auto_typekeyword automatically causes its type to be derived based on the type of its initializer.__auto_typeis similar to theautokeyword in C++11, but more limited in when it can be used. This is an extension found in the GNU C compiler.