3

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.

  • 4
    The `register` keyword is archaic. Modern compilers completely ignore it except for its semantics. – Mysticial Jun 14 '15 at 04:58
  • Oh, but why? Why is it ignored? This storage class can really be helpful during optimisations, if there are many variables. –  Jun 14 '15 at 05:00
  • How would say, you could determine if you are *never* going to use & operator _at_ the time of declaring a variable? And if this happens to be a part of some library code, then what? – Yogesh Jun 14 '15 at 05:01
  • 1
    Because modern compilers can do register allocation better than the vast majority of humans. – Mysticial Jun 14 '15 at 05:02
  • Say, I'm writing a simple program: Take an input from user and store it in a variable 'x', and then add it to a variable say 'y' (initialized with some value already) and then print 'y'. Here I'm not working with the address of 'x' - just using it for storing. –  Jun 14 '15 at 05:04
  • 3
    Since this is tagged c++, `register` was deprecated in c++11 and will be removed from c++17. – user657267 Jun 14 '15 at 05:06
  • @Mysticial: Even if compilers were not better, I'd rather waste the compiler's time than my own time. – gnasher729 Jun 14 '15 at 05:17
  • You ask: "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". This is essentially what happens when the `register` keyword is *not* used: the compiler will decide what goes into a register (the scenario you described when the set of registers 'ran out' when everything was declared using the `register` storage class). This is basically why the `register` keyword is generally considered redundant/useless/unnecessary/whatever. – Michael Burr Jun 14 '15 at 07:18
  • 1
    "Unavailability of the address" isn't a drawback, it's a feature. The keyword gives you a chance to restrict your use of a variable slightly and raise compile-time errors if you violate your own promise. It gives the compiler a chance to curtail the errors of a human designer. *That's a good thing*. It's a pity C doesn't have more features like this, since `register` isn't really powerful enough to achieve much on its own. In other words, there is no reason not to use it everywhere except for peer pressure. – Leushenko Sep 02 '15 at 04:03
  • @Leushenko: I would suggest that `register` would be more useful if it allowed for pass a variable's address to a function if the pointer will never be used after the function returns. Calling `foo(&x);` would then be equivalent to `{int temp=x; foo(&temp); x=temp;}`, but would allow a compiler to treat x as a variable whose address is never taken. Likewise allowing globals to be declared `register` would let a compiler know that it need not consider the possibility of pointers aliasing them except during the lifetime of functions to which they are passed. – supercat May 09 '16 at 21:02

2 Answers2

6

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

Community
  • 1
  • 1
Basile Starynkevitch
  • 216,767
  • 17
  • 275
  • 509
  • And what if I'm not going to work on its address (as I have already pointed out in the question)? Can I use register storage class then? –  Jun 14 '15 at 05:01
  • 4
    You can, but it is useless. – Basile Starynkevitch Jun 14 '15 at 05:02
  • 6
    @abhishek_naik In addition to being useless, if you use the register keyword in new code other C/C++ programmers will point and laugh at you. – Ross Ridge Jun 14 '15 at 05:14
  • Would you see any problem with saying that `register` on an auto or global variable would entitle a compiler to assume that no pointer to that variable will alias it outside the context where such a pointer is created, thus entitling a compiler to assume that after `register int x,y; get_two_numbers(&x,&y);` the compiler may treat `x` and `y` as variables to which no outside pointers can possibly exist? – supercat May 09 '16 at 21:06
3

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

gnasher729
  • 49,784
  • 5
  • 72
  • 94