Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why was the register keyword created?

While reading Keywords That Aren't (or, Comments by Another Name) by Herb Sutter I came across these lines:

That's right, some keywords are semantically equivalent to whitespace, a glorified comment.

And

We've seen why the C++ language treats keywords as reserved words, and we've seen two keywords —auto and register — that make no semantic difference whatsoever to a C++ program. Don't use them; they're just whitespace anyway, and there are faster ways to type whitespace.

If the keywords like auto(maybe not in C++11) and register are of no value, then why were they created and used?

If it doesn't make any difference to include the register before a variable

#include<stdio.h>
int main(){
    register int a = 15;
    printf("%d\n%d\n",&a,a);
    return 0;
}

Why does the above program give an error?

test_register.c: In function ‘main’:

test_register.c:4:2: error: address of register variable ‘a’ requested

printf("%d\n%d\n",&a,a);

The following program works in C++.

#include<iostream>
int main(){
    register int a = 15;
    std::cout<<&a<<'\n'<<a;
    return 0;
}
like image 553
ayushgp Avatar asked May 26 '16 09:05

ayushgp


People also ask

What is the purpose of register keyword?

Register variables tell the compiler to store the variable in CPU register instead of memory. Frequently used variables are kept in registers and they have faster accessibility. We can never get the addresses of these variables.

Is register a keyword?

In the C programming language, register is a reserved word (or keyword), type modifier, storage class, and hint.

What is the original intent of using register int i?

It tells the compiler to try to use a CPU register, instead of RAM, to store the variable. Registers are in the CPU and much faster to access than RAM.

When should the register modifier be used?

When should the register modifier be used? Does it really help? The register modifier hints to the compiler that the variable will be heavily used and should be kept in the CPU's registers, if possible, so that it can be accessed faster.


3 Answers

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

like image 109
Theodoros Chatzigiannakis Avatar answered Sep 26 '22 00:09

Theodoros Chatzigiannakis


register in C served two purposes:

  • Hint to the compiler that the variable should be stored in a register for performance. This use is largely obsolete now.
  • Prevent the programmer from using the variable in ways that would prevent it from being stored in a register. This use is only somewhat obsolete IMO.

This is similar to const, which

  • Hints to the compiler that a variable may be stored in read-only memory.
  • Prevents the programmer from writing to the variable

As an example, consider this simplistic function:

int sum(const int *values, size_t length) {
    register int acc = 0;
    for (size_t i = 0; i < length; ++i) {
        acc += values[i];
    }
    return acc;
}

The programmer has written register to keep the accumulator off the stack, avoiding a memory write every time it's updated. If the implementation gets changed to something like this:

// Defined in some other translation unit
void add(int *dest, int src);

int sum(const int *values, size_t length) {
    register int acc = 0;
    for (size_t i = 0; i < length; ++i) {
        add(&acc, values[i]);
    }
    return acc;
}

The acc variable can no longer be stored in a register when its address is taken for the add() call, because registers have no address. The compiler will thus flag &acc as an error, letting you know that you've probably destroyed the performance of your code by preventing acc from living in a register.

This used to be a lot more important in the early days when compilers were dumber and variables would live in a single place for an entire function. Nowadays a variable can spend most of its life in a register, being moved onto the stack only temporarily when its address is taken. That is, this code:

/* Passed by reference for some reason. */
void debug(const int *value);

int sum(const int *values, size_t length) {
    int acc = 0;
    for (size_t i = 0; i < length; ++i) {
        acc += values[i];
    }
    debug(&acc);
    return acc;
}

would have caused acc to live on the stack for the whole function in older compilers. Modern compilers will keep acc in a register until just before the debug() call.

Modern C code does not generally use the register keyword.

like image 45
Tavian Barnes Avatar answered Sep 23 '22 00:09

Tavian Barnes


C99 Rationale provides some more context of keyword register:

Rationale for International Standard — Programming Languages — C

§6.7.1 Storage-class specifiers

Because the address of a register variable cannot be taken, objects of storage class register effectively exist in a space distinct from other objects. (Functions occupy yet a third address space.) This makes them candidates for optimal placement, the usual reason for declaring registers; but it also makes them candidates for more aggressive optimization.

like image 37
Yu Hao Avatar answered Sep 27 '22 00:09

Yu Hao



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!