Skip to main content

IAR Embedded Workbench for Arm 9.70.x

Type qualifiers

In this section:

According to the C standard, volatile and const are type qualifiers.

Declaring objects volatile

By declaring an object volatile, the compiler is informed that the value of the object can change beyond the compiler’s control. The compiler must also assume that any accesses can have side effects—therefore all accesses to the volatile object must be preserved.

There are three main reasons for declaring an object volatile:

  • Shared access—the object is shared between several tasks in a multitasking environment

  • Trigger access—as for a memory-mapped SFR where the fact that an access occurs has an effect

  • Modified access—where the contents of the object can change in ways not known to the compiler.

Definition of access to volatile objects

The C standard defines an abstract machine, which governs the behavior of accesses to volatile declared objects. In general and in accordance to the abstract machine:

  • The compiler considers each read and write access to an object declared volatile as an access

  • The unit for the access is either the entire object or, for accesses to an element in a composite object—such as an array, struct, class, or union—the element. For example:

    char volatile a;
    a = 5;   /* A write access */
    a += 6;  /* First a read then a write access */
  • An access to a bitfield is treated as an access to the underlying type

  • Adding a const qualifier to a volatile object will make write accesses to the object impossible. However, the object will be placed in RAM as specified by the C standard.

However, these rules are not detailed enough to handle the hardware-related requirements. The rules specific to the IAR C/C++ Compiler for Arm are described below.

Rules for accesses

In the IAR C/C++ Compiler for Arm , accesses to volatile declared objects are subject to these rules:

  • All accesses are preserved

  • All accesses are complete, that is, the whole object is accessed

  • All accesses are performed in the same order as given in the abstract machine

  • All accesses are atomic, that is, they cannot be interrupted.

The compiler adheres to these rules for accesses to all 8-, 16-, and 32-bit scalar types, except for accesses to unaligned 16- and 32-bit fields in packed structures.

For all combinations of object types not listed, only the rule that states that all accesses are preserved applies.

Declaring objects volatile and const

If you declare a volatile object const, it will be write-protected but it will still be stored in RAM memory as the C standard specifies.

To store the object in read-only memory instead, but still make it possible to access it as a const volatile object, declare it with the __ro_placement attribute. See __ro_placement.

Declaring objects const

The const type qualifier is used for indicating that a data object, accessed directly or via a pointer, is non-writable. A pointer to const declared data can point to both constant and non-constant objects. It is good programming practice to use const declared pointers whenever possible because this improves the compiler’s possibilities to optimize the generated code and reduces the risk of application failure due to erroneously modified data.

Static and global objects declared constare allocated in ROM.

In C++, objects that require runtime initialization cannot be placed in ROM.