| |||
| Home > ARM Compiler Reference > Compiler-specific features > Variable declaration keywords | |||
This section describes the implementation of various standard
and ARM-specific variable declaration keywords. Standard C or C++
keywords that do not have ARM-specific behavior or restrictions
are not documented. See also Type qualifiers for information on qualifiers such as volatile,
and __packed.
The following keywords can be used only on local variables.
You can declare any number of auto variables to have the storage class register. Depending on the variant of the ARM Procedure Call Standard (APCS) that is in use, there are between five and seven integer registers available, and four floating-point registers.
In general, declaring more than four integer register variables and two floating-point register variables is not recommended.
Objects of the following types can be declared to have the register storage class:
Any integer type.
Any pointer type.
Any integer-like structure, such as any one word struct or union in which all addressable fields have the same address, or any one word structure containing bitfields only. The structure must be padded to 32 bits.
A floating-point type. The double precision floating-point type double occupies two ARM registers if the software floating-point library is used.
The register keyword is regarded by the compiler as a suggestion only. Other variables, not declared with the register keyword, may be held in registers for extended periods and register variables may be held in memory for some periods.
The following keywords can be used only on global variables.
The following variable declaration keywords allow you to specify that a declared variable is allocated to a global register variable:
__global_reg(n)Allocates the declared variable to a global integer register variable. Global register variables cannot be qualified or initialized at declaration. Valid types are:
Any integer type except long long.
Any pointer type.
__global_freg(n)Allocates the declared variable to a global floating-point
register variable. The variable must have type float or double.
This keyword is legal only if -fpu fpa or -apcs
/hardfp is specified.
The global register must be specified in all declarations of the same variable. For example, the following is an error:
int x; __global_reg(1) x; // error
In addition, __global_reg variables in
C cannot be initialized at definition. For example, the following
is an error in C, and not in C++:
__global_reg(1) int x=1; /* error */
Depending on the APCS variant in use, between five and seven integer registers and four floating-point registers are available for use as global register variables. In practice, using more than three global integer register variables and two global floating-point register variables is not recommended.
Unlike register variables declared with the standard register keyword, the compiler will not move global register variables to memory as required. If you declare too many global variables, code size will increase significantly or, in some cases, your program may not compile.
Note the following important points:
You must exercise care when using global register variables. There is no check at link time to ensure that direct calls are sensible. If possible, any global register variables used in a program should be defined in each compilation unit of the program. In general, it is best to place the definition in a global header file.
Because a global register variable maps to a callee-saved register, its value is saved and restored across a call to a function in a compilation unit that does not use it as a global register variable, such as a library function.
Calls back into a compilation unit that uses a global register variable are dangerous. For example, if a global register using function is called from a compilation unit that does not declare the global register variable, the function will read the wrong values from its supposed global register variables.