Skip to main content

IAR Embedded Workbench for RH850 3.20.x

IAR C language extensions

In this section:

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 #pragma location can 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 #pragma pack directive, and the #pragma data_alignment directive 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 int or unsigned 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:

__section_begin

Returns the address of the first byte of the named section or block.

__section_end

Returns the address of the first byte after the named section or block.

__section_size

Returns the size of the named section or block in bytes.

Note

The aliases __segment_begin/__sfb, __segment_end/__sfe, and __segment_size/__sfs can also be used.

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

__section_begin(sec)

sec$$Base

__section_end(sec)

sec$$Limit

__section_size(sec)

sec$$Length

Table 70. Section operators and their symbols  


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 __brel*.

#pragma section="MYSECTION" __brel
...
section_start_address = __section_begin("MYSECTION");

See also section, and location.

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:

  • Arrays of incomplete types

    An array can have an incomplete struct, union, or enum type 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).

  • Zero-length arrays

    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 enum types

    The extensions allow you to first declare the name of an enum and later resolve it by specifying the brace-enclosed list.

  • Accepting missing semicolon at the end of a struct or union specifier

    A warning—instead of an error—is issued if the semicolon at the end of a struct or union specifier is missing.

  • Null and void

    In operations on pointers, a pointer to void is 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 float means double

    The type long float is accepted as a synonym for double.

  • Binary integer literals (0b...) are supported.

  • Digit separators for integer literals (1'000'000) are supported.

  • Repeated typedef declarations

    Redeclarations of typedef that occur in the same scope are allowed, but a warning is issued.

  • Mixing pointer types

    Assignment and pointer difference is allowed between pointers to types that are interchangeable but not identical, for example, unsigned char * and char *. 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.

  • Non-lvalue arrays

    A non-lvalue array 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 enum lists

    Placing an extra comma is allowed at the end of an enum list. 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 switch statements.

  • Empty declarations

    An empty declaration (a semicolon by itself) is allowed, but a remark is issued (provided that remarks are enabled).

  • Single-value initialization

    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 y can be used at the end of the function, even though it should only be visible in the body of the if statement. 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-number syntax. Therefore, 0x123e+1 is scanned as three tokens instead of one valid token. (If the ‑‑strict option is used, the pp-number syntax is used instead.)

  • Empty translation unit

    A translation unit (input file) might be empty of declarations.

  • Assignment of pointer types

    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 ** to const 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

    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 asm function.

  • #include_next

    The non-standard preprocessing directive #include_next is supported. This is a variant of the #include directive. 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_next directive) is found. This is an extension found in the GNU C compiler.

  • #warning

    The non-standard preprocessing directive #warning is supported. It is similar to the #error directive, 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.

  • Concatenating strings

    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};

  • typeof

    The non-standard operator typeof is supported when IAR extensions are enabled, as a way of referring to the type of an expression. The syntax is like that of sizeof, but it behaves semantically like a type name defined with typedef. This is an extension found in the GNU C compiler.

  • __auto_type

    The non-standard keyword __auto_type is supported when IAR extensions are enabled. Declaring a variable with the __auto_type keyword automatically causes its type to be derived based on the type of its initializer. __auto_type is similar to the auto keyword in C++11, but more limited in when it can be used. This is an extension found in the GNU C compiler.