Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"register" keyword in C?

Tags:

c

memory

keyword

People also ask

Is register a keyword?

In the C programming language, register is a reserved word (or keyword), type modifier, storage class, and hint.

What is the register variable?

Register variables are a special case of automatic variables. Automatic variables are allocated storage in the memory of the computer; however, for most computers, accessing data in memory is considerably slower than processing in the CPU.

What is static and register in C?

register is used to store the variable in CPU registers rather memory location for quick access. Static is used for both global and local variables. Each one has its use case within a C program. Extern is used for data sharing between C project files.

What is register in embedded C?

Many devices have multiple internal registers, but only respond to a single address. To access a specific register, the code first needs to write the register number to the device and then perform the required write/read operation. This is not difficult, but needs to be managed carefully.


It's a hint to the compiler that the variable will be heavily used and that you recommend it be kept in a processor register if possible.

Most modern compilers do that automatically, and are better at picking them than us humans.


I'm surprised that nobody mentioned that you cannot take an address of register variable, even if compiler decides to keep variable in memory rather than in register.

So using register you win nothing (anyway compiler will decide for itself where to put the variable) and lose the & operator - no reason to use it.


It tells the compiler to try to use a CPU register, instead of RAM, to store the variable. Registers are in the CPU and much faster to access than RAM. But it's only a suggestion to the compiler, and it may not follow through.


I know this question is about C, but the same question for C++ was closed as a exact duplicate of this question. This answer therefore may not apply for C.


The latest draft of the C++11 standard, N3485, says this in 7.1.1/3:

A register specifier is a hint to the implementation that the variable so declared will be heavily used. [ note: The hint can be ignored and in most implementations it will be ignored if the address of the variable is taken. This use is deprecated ... —end note ]

In C++ (but not in C), the standard does not state that you can't take the address of a variable declared register; however, because a variable stored in a CPU register throughout its lifetime does not have a memory location associated with it, attempting to take its address would be invalid, and the compiler will ignore the register keyword to allow taking the address.


It hasn't been relevant for at least 15 years as optimizers make better decisions about this than you can. Even when it was relevant, it made a lot more sense on a CPU architecture with a lot of registers, like SPARC or M68000 than it did on Intel with its paucity of registers, most of which are reserved by the compiler for its own purposes.


I have read that it is used for optimizing but is not clearly defined in any standard.

In fact it is clearly defined by the C standard. Quoting the N1570 draft section 6.7.1 paragraph 6 (other versions have the same wording):

A declaration of an identifier for an object with storage-class specifier register suggests that access to the object be as fast as possible. The extent to which such suggestions are effective is implementation-defined.

The unary & operator may not be applied to an object defined with register, and register may not be used in an external declaration.

There are a few other (fairly obscure) rules that are specific to register-qualified objects:

  • Defining an array object with register has undefined behavior.
    Correction: It's legal to define an array object with register, but you can't do anything useful with such an object (indexing into an array requires taking the address of its initial element).
  • The _Alignas specifier (new in C11) may not be applied to such an object.
  • If the parameter name passed to the va_start macro is register-qualified, the behavior is undefined.

There may be a few others; download a draft of the standard and search for "register" if you're interested.

As the name implies, the original meaning of register was to require an object to be stored in a CPU register. But with improvements in optimizing compilers, this has become less useful. Modern versions of the C standard don't refer to CPU registers, because they no longer (need to) assume that there is such a thing (there are architectures that don't use registers). The common wisdom is that applying register to an object declaration is more likely to worsen the generated code, because it interferes with the compiler's own register allocation. There might still be a few cases where it's useful (say, if you really do know how often a variable will be accessed, and your knowledge is better than what a modern optimizing compiler can figure out).

The main tangible effect of register is that it prevents any attempt to take an object's address. This isn't particularly useful as an optimization hint, since it can be applied only to local variables, and an optimizing compiler can see for itself that such an object's address isn't taken.