0

I read one some question on SO (unfortunately I don't remember the question) that two keywords that should never be used are goto and register. Now, I didn't even know what on earth register is before this, so I looked it up and found another question here that showed some uses for registers. Sure, register values have their disadvantages, but I also see some uses. Plus, the compiler can always veto the choice to actually use the registers. So if you know the limitations when using register, why not use them?

mediocrevegetable1
  • 4,086
  • 1
  • 11
  • 33
  • 1
    First of all, C and C++ are two very different languages, with their own distinct specifications. And the keyword `register` is specified differently in the two languages. – Some programmer dude Jan 27 '21 at 06:27
  • This seems identical to the question you linked really – M.M Jan 27 '21 at 06:27
  • 1
    As for `goto`, please do some research about *spaghetti code*. – Some programmer dude Jan 27 '21 at 06:28
  • Thank you for the comments, I removed the C++ tag. @M.M the reason why I asked the question is that I basically never see the keyword being used anywhere and was wondering if it was considered bad practice by everyone. – mediocrevegetable1 Jan 27 '21 at 06:29
  • @Someprogrammerdude I am aware of why `goto` is very bad, I just said it because I was explaining the context in which I heard `register`. – mediocrevegetable1 Jan 27 '21 at 06:30
  • 7
    *Misuse* of `goto` is bad, but there are niche uses for it that make code clearer and therefore better. On the other hand, modern compilers do a better job of allocating registers than humans can, so declaring variables with `register` storage class gains you nothing, but it costs you the ability to take the variable's address with the `&` operator, and, therefore, the ability to access that variable indirectly. `register` is functionally obsolete. Not so much `goto`. – John Bollinger Jan 27 '21 at 06:34
  • I remember having lately seen questions which were of the sort: "why is this code using `register` slower than without" - and the answer is "because you told the compiler to put **that** variable into a register" – Antti Haapala -- Слава Україні Jan 27 '21 at 07:23
  • 1
    I see. I guess now compilers are so optimized that they are far better at deciding whether to put a variable as a register or not. – mediocrevegetable1 Jan 27 '21 at 07:29
  • 2
    @mediocrevegetable1 "compilers are optimised" is not the point. Compiler are far better than humans to generate efficient machine code, that's it. The fact that a compiler is optimised or not is another thing. – Jean-Baptiste Yunès Jan 27 '21 at 08:05

2 Answers2

4
  1. Using compilers from circa pre-1990 with exuberant use of register could, and probably would, hobble them to placing too much faith in the programmer and generate non-optimal code.

  2. Most (virtually all) compilers are now "smart" enough to determine themselves whether the given set of register variables are helpful and probably totally ignore them.

  3. Circa 1973 (Unix V6), the register storage class was extremely valuable to scrunch PDP-11 code to compile small enough to so that the kernel could fit in its 64 KiB space. Speed is fine, but in those days it was about code size.

wallyk
  • 56,922
  • 16
  • 83
  • 148
  • 2
    I guess that does seem to make sense. Thank you for taking your time out to answer. – mediocrevegetable1 Jan 27 '21 at 06:38
  • 1
    > the kernel could fit in its 64 KiB space The mind boggles. I remember getting my feelings hurt 20 years ago when I got my hands on a Mandrake CD, and finding out it required a minimum of 64 MEGAbytes when I only had 16 megs on the 486. – Arthur Kalliokoski Jan 27 '21 at 07:53
  • 1
    @ArthurKalliokoski: Yep. I do kind-of miss the good old days when it was *possible* to know everything about what was in the address space: data and program. – wallyk Jan 29 '21 at 06:46
2

register is mostly a superfluous keyword that was historically used for manually optimizing code. Very old compilers were sometimes too dumb to realize that a variable that doesn't have its address taken could often be stored in a CPU register rather than on the stack, which is a major performance improvement.

Not only are registers the fastest type of memory in a computer, much faster than RAM where the stack sits. But if allocating in a register, the compiler can also leave out the extra code for pushing/popping the variable on the stack.

Normal, modern C programs should however never use register since compilers are nowadays much more capable than programmers when it comes to determining where to allocate a certain variable. The keyword has been "de facto" obsolete since somewhere in the mid 1990s, though it has not been flagged formally obsolete by the C standard yet.

So if you encounter code containing register, it is either extremely old, or (far more likely) the programmer didn't quite have a clue what they were doing when they tried to manually optimize something.


There are some very limited, advanced "language-lawyer" uses of the keyword still. Namely that such a variable can never have its address taken. The address-of operator 6.5.3.2 states (emphasis mine):

The operand of the unary & operator shall be either a function designator, the result of a [] or unary * operator, or an lvalue that designates an object that is not a bit-field and is not declared with the register storage-class specifier.

This might matter in cases such as determining if accessing an uninitialized variable with indeterminate value is undefined behavior or merely unspecified behavior. See (Why) is using an uninitialized variable undefined behavior?

Lundin
  • 195,001
  • 40
  • 254
  • 396