The register storage class specifier

The register storage class specifier indicates to the compiler that the object should be stored in a machine register. The register storage class specifier is typically specified for heavily used variables, such as a loop control variable, in the hopes of enhancing performance by minimizing access time. However, the compiler is not required to honor this request. Because of the limited size and number of registers available on most systems, few variables can actually be put in registers. If the compiler does not allocate a machine register for a register object, the object is treated as having the storage class specifier auto.

An object having the register storage class specifier must be defined within a block or declared as a parameter to a function.

The following restrictions apply to the register storage class specifier:

C++ only Unlike C, C++ lets you take the address of an object with the register storage class. For example:
   register int i;
   int* b = &i;      // valid in C++, but not in C

Storage duration of register variables

Objects with the register storage class specifier have automatic storage duration. Each time a block is entered, storage for register objects defined in that block is made available. When the block is exited, the objects are no longer available for use.

If a register object is defined within a function that is recursively invoked, a new object is allocated at each invocation of the block.

Linkage of register variables

Since a register object is treated as the equivalent to an object of the auto storage class, it has no linkage.

Variables in specified registers (IBM extension)

You can specify that a particular hardware register is dedicated to a variable by using an asm register variable declaration. This language extension is provided for compatibility with GNU C.

Global register variables reserve registers throughout the program; stores into the reserved register are never deleted.

Local register variables do not actually reserve the registers, except when the variables are used as input or output operands in an inline assembly statement. In this case, using the variable as an asm operand guarantees that the specified register is used for the operand and is a convenient way to control which register is used.

Read syntax diagramSkip visual syntax diagram
Register variable declaration syntax

>>-register--variable_declaration------------------------------->

>--+-asm-----+-("register_specifier")--------------------------><
   +-__asm__-+                          
   '-__asm---'                          

The register_specifier is a string representing a hardware register. The register name is CPU-specific. The following are valid register names:
r0 to r31
General purpose registers
f0 to f31
Floating-point registers
v0 to v31
Vector registers (on selected processors)
The following are the rules of use for register variables:
  • You cannot reserve registers for the following types of variables:
    • long long types
    • aggregate types
    • C++ only class types
    • C++ only reference types
    • void types
    • _Complex types
    • 128-bit long double types
    • decimal floating-point types
  • General purpose registers can only be reserved for variables of integer or pointer type.
  • Floating-point registers can only be reserved for variables of float, double, or 64-bit long double type.
  • Vector registers can only be reserved for variables of vector type.
  • A global register variable cannot be initialized.
  • The register dedicated for a global register variable should not be a volatile register, or the value stored into the global variable might not be preserved across a function call.
  • More than one register variable can reserve the same register; however, the two variables become aliases of each other, and this is diagnosed with a warning.
  • The same global register variable cannot reserve more than one register.
  • A register variable should not be used in an OpenMP clause or OpenMP parallel or work-sharing region.
  • The register specified in the global register declaration is reserved for the declared variable only in the compilation unit in which the register declaration is specified. The register is not reserved in other compilation units unless you place the global register declaration in a common header file, or use the -qreserved_reg compiler option.