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

3.3k Views Asked by At

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.

2

There are 2 best solutions below

4
On BEST ANSWER

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++.

1
On

The "register" keyword is just a hint to the compiler that you think the variable should be handled quicker than others, if possible. As a side effect, taking the address of the variable is not allowed, and register arrays are undefined behaviour.

Any modern compiler will use registers anyway as much as possible, so this keyword is not needed anymore. The compiler is also more clever than you: It can use a register for variable x in one part and for variable y in another part of the program. Or use registers for two of five fields of a struct. All things that you cannot even express with the register keyword.

The only case where using register may be not completely pointless is when you have a variable that looks like it is used much less than others, but you know better. Even then it is a very big "may".