Search code examples
c++cstorage-class-specifier

Why can't we always use the register storage class in C?


I read in a book that, whenever we declare a variable with the storage class as register, then it would be stored in a register, subject to the its availability. If no register is available, then the default storage type of 'auto' would be assigned to it.

Whenever we declare a variable without explicitly mentioning any storage class, then the default storage type assigned to it is 'auto' itself.

So, my question is, why not declare every variable to be of the 'register' storage class - if no register is available, it will anyways be treated as the default 'auto' class itself. And luckily, if registers are available, then it would be stored in one. I understand that we cannot use the & operator any longer, but what if I'm not going to work with pointers and addresses? Can I declare those variables with the 'register' storage class then? Because this seems to be a bad practise.

Edit: I searched the web, but 'unavailability of the address' is the only point mentioned. Why can't the rest variables be declared with 'register' is not mentioned.


Solution

  • You cannot make all your variables register, because the C (and (C++) language specification(s) explicitly forbids taking the address of a register variable.

    However, the register qualifier is not having any role in today's optimizing compilers like GCC or Clang/LLVM and these compilers will happily and freely use a machine register for variables not qualified register or even keep in memory (not in a machine register) a variable qualified as register. Essentially the compiler is ignoring the register qualifier (except to forbid taking its address). It has complex register allocation algorithms and heuristics. A given variable might stay in a machine register for some parts of the function code, and be put in memory for other parts.

    From an optimization point of view, current compilers handle auto and register qualified variables in the same way (hence the register qualifier is useless, except to forbid the address-of operator).

    Notice also the the CPU cache is much more important than processor registers today. If you want to hand-tune your C code for performance (which is often a bad idea, since the compiler is doing better than you can), better take care of caching issues (see this).

    AFAIK, future versions of the C and C++ languages would officially deprecate the register qualifier (as they did for the auto qualifier), and it could happen that future language specifications would reuse that keyword for other purposes (as C++11 reused auto). So using register in your source code is probably a mistake, since it might make your code harder to port to future versions of C or C++.