Register Keyword in C++

register keyword in C?

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.

Should I use the register keyword in my code?

The register keyword was intended as an optimization hint to the compiler. The problem is, the compiler knows your code better than you do, and these days do not need such simplistic hints to generate better code.

So the only thing register does with modern compilers is prevent you from using & to take the address of the variable. That's it.

Register keyword in C++

In C++ as it existed in 2010, any program which is valid that uses the keywords "auto" or "register" will be semantically identical to one with those keywords removed (unless they appear in stringized macros or other similar contexts). In that sense the keywords are useless for properly-compiling programs. On the other hand, the keywords might be useful in certain macro contexts to ensure that improper usage of a macro will cause a compile-time error rather than producing bogus code.

In C++11 and later versions of the language, the auto keyword was re-purposed to act as a pseudo-type for objects which are initialized, which a compiler will automatically replace with the type of the initializing expression. Thus, in C++03, the declaration: auto int i=(unsigned char)5; was equivalent to int i=5; when used within a block context, and auto i=(unsigned char)5; was a constraint violation. In C++11, auto int i=(unsigned char)5; became a constraint violation while auto i=(unsigned char)5; became equivalent to auto unsigned char i=5;.

Why was the register keyword created?


register

In C, the register storage class was used as a hint to the compiler, to express that a variable should be preferentially stored in a register. Note that the hint to store a register variable in an actual register may or may not be honored, but in either case the relevant restrictions still apply. See C11, 6.7.1p6 (emphasis mine):

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.[footnote 121]

[footnote 121] The implementation may treat any register declaration simply as an auto declaration. However, whether or not addressable storage is actually used, the address of any part of an object declared with storage-class specifier register cannot be computed, either explicitly (by use of the unary & operator as discussed in 6.5.3.2) or implicitly (by converting an array name to a pointer as discussed in 6.3.2.1). Thus, the only operators that can be applied to an array declared with storage-class specifier register are sizeof and _Alignof.

In C++ it is simply an unused reserved keyword, but it's reasonable to assume that it was kept for syntactical compatibility with C code.

auto

In C, the auto storage class defines a variable of automatic storage, but it's not usually used since function-local variables are auto by default.

Similarly, it's reasonable to assume that it was initially carried over to C++ for syntactical compatibility only, although later it got its own meaning (type inference).

What's wrong with register keyword in C++?

You've pretty much answered your own question:

I think modern compilers are very smart so they implicitly optimizes frequently used variables for speed (fast access) & puts them in CPU register.

That's precisely the point—optimisers are so good at register allocation nowadays that any attempt from the programmer to enforce their will through the register keyword would likely lead to a pessimisatin, and is therefore simply ignored by the compiler. Remember that register was never a binding requirement, always just a hint to the compiler. Now that they rightfully scoff at such hints, the keyword is simply obsolete and useless.

So, to directly answer your question of "what's wrong with it:" it no longer serves any purpose whatsoever, as the only one it ever had ("hint to the compiler to put this thing in a register") is now superseded by the compilers being way better at this than humans.

Concept of register variables(datatype:register) in C language?

The register keyword in C (rarely ever seen anymore) is only a hint to the compiler that it may be useful to keep a variable in a register for faster access.

The compiler is free to ignore the hint, and optimize as it sees best.

Since modern compilers are much better than humans at understanding usage and speed, the register keyword is usually ignored by modern compilers, and in some cases, may actually slow down execution speed.

How can I ivestigate use of the register keyword in C?

Today, with optimizing compilers (like GCC with -O1 at least), the register keyword is indeed deprecated. Its only meaning is to forbid taking the address of such a declared variable.

In other words,

  register int r;
printf("r@%p\n", &r); // WRONG: address of register variable

should not compile.

GCC also provides as an extension (also understood by Clang/LLVM) variables in specified register.

You might look inside the assembler code (file *.s), e.g. produced with gcc -Wall -O2 -S -fverbose-asm...

BTW, on current machines, the CPU cache and the locality of data matters a lot regarding to performance, probably much more than register usage (of course, assuming optimizations are enabled in your compiler). Read also about register renaming, and this answer (related to prefetching).

Is the register keyword still used?

Most implementations just ignore the register keyword (unless it imposes a syntactical or semantical error).

The standard also doesn't say that anything must be kept in a register; merely that it's a hint to the implementation that the variable is going to be used very often. Its use is even deprecated.

7.1.1 Storage class specifiers [dcl.stc]


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 (see D.2). — end note ]

Replacement for deprecated register keyword C++ 11

We can find the rationale for deprecating register in defect report 809: Deprecation of the register keyword which says (emphasis mine):

The register keyword serves very little function, offering no more
than a hint that a note says is typically ignored
. It should be
deprecated in this version of the standard, freeing the reserved name
up for use in a future standard, much like auto has been re-used this
time around for being similarly useless.

The removal of register for C++17 was approved in the Lenexa meeting but it is still reserved for future use.

The register keyword was deprecated in the 2011 C++ standard, as its
effect was already implicit in the language
. It remains reserved for
future use by the standard, and is time to remove its vestigial
specification.

Because of the as-if rule the compiler only has to emulate the observable behavior of the program and therefore the optimizer can via the as-if rule choose to keep a variable in a register if it won't effect observable behavior and presumably will in most cases make better choices since it usually has more information.

For reference also see role of "register" C keyword? from the gcc mailing list, one of the replies in the thread says:

I don't think the "register" keyword ever affected register allocation
in gcc. For that you have to go back to compilers of the 1970s.

The register keyword does still have a use, though, in a gcc
extension: gcc uses it in combination with asm to implement register
variables.



Related Topics



Leave a reply



Submit