“register” keyword in C?

2019-01-01 06:27发布

What does the register keyword do in C language? I have read that it is used for optimizing but is not clearly defined in any standard. Is it still relevant and if so, when would you use it?

标签: c memory keyword
17条回答
公子世无双
2楼-- · 2019-01-01 06:55

It's a hint to the compiler that the variable will be heavily used and that you recommend it be kept in a processor register if possible.

Most modern compilers do that automatically, and are better at picking them than us humans.

查看更多
泛滥B
3楼-- · 2019-01-01 06:56

You are messing with the compiler's sophisticated graph-coloring algorithm. This is used for register allocation. Well, mostly. It acts as a hint to the compiler -- that's true. But not ignored in its entirety since you are not allowed to take the address of a register variable (remember the compiler, now on your mercy, will try to act differently). Which in a way is telling you not to use it.

The keyword was used long, long back. When there were only so few registers that could count them all using your index finger.

But, as I said, deprecated doesn't mean you cannot use it.

查看更多
冷夜・残月
4楼-- · 2019-01-01 06:56

On supported C compilers it tries to optimize the code so that variable's value is held in an actual processor register.

查看更多
与君花间醉酒
5楼-- · 2019-01-01 07:00

During the seventies, at the very beginning of the C language, the register keyword has been introduced in order to allow the programmer to give hints to the compiler, telling it that the variable would be used very often, and that it should be wise to keep it’s value in one of the processor’s internal register.

Nowadays, optimizers are much more efficient than programmers to determine variables that are more likely to be kept into registers, and the optimizer does not always take the programmer’s hint into account.

So many people wrongly recommend not to use the register keyword.

Let’s see why!

The register keyword has an associated side effect: you can not reference (get the address of) a register type variable.

People advising others not to use registers takes wrongly this as an additional argument.

However, the simple fact of knowing that you can not take the address of a register variable, allows the compiler (and its optimizer) to know that the value of this variable can not be modified indirectly through a pointer.

When at a certain point of the instruction stream, a register variable has its value assigned in a processor’s register, and the register has not been used since to get the value of another variable, the compiler knows that it does not need to re-load the value of the variable in that register. This allows to avoid expensive useless memory access.

Do your own tests and you will get significant performance improvements in your most inner loops.

c_register_side_effect_performance_boost

查看更多
余生无你
6楼-- · 2019-01-01 07:01

Actually, register tells the compiler that the variable does not alias with anything else in the program (not even char's).

That can be exploited by modern compilers in a variety of situations, and can help the compiler quite a bit in complex code - in simple code the compilers can figure this out on their own.

Otherwise, it serves no purpose and is not used for register allocation. It does not usually incur performance degradation to specify it, as long as your compiler is modern enough.

查看更多
只若初见
7楼-- · 2019-01-01 07:04

I have read that it is used for optimizing but is not clearly defined in any standard.

In fact it is clearly defined by the C standard. Quoting the N1570 draft section 6.7.1 paragraph 6 (other versions have the same wording):

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.

The unary & operator may not be applied to an object defined with register, and register may not be used in an external declaration.

There are a few other (fairly obscure) rules that are specific to register-qualified objects:

  • Defining an array object with register has undefined behavior.
    Correction: It's legal to define an array object with register, but you can't do anything useful with such an object (indexing into an array requires taking the address of its initial element).
  • The _Alignas specifier (new in C11) may not be applied to such an object.
  • If the parameter name passed to the va_start macro is register-qualified, the behavior is undefined.

There may be a few others; download a draft of the standard and search for "register" if you're interested.

As the name implies, the original meaning of register was to require an object to be stored in a CPU register. But with improvements in optimizing compilers, this has become less useful. Modern versions of the C standard don't refer to CPU registers, because they no longer (need to) assume that there is such a thing (there are architectures that don't use registers). The common wisdom is that applying register to an object declaration is more likely to worsen the generated code, because it interferes with the compiler's own register allocation. There might still be a few cases where it's useful (say, if you really do know how often a variable will be accessed, and your knowledge is better than what a modern optimizing compiler can figure out).

The main tangible effect of register is that it prevents any attempt to take an object's address. This isn't particularly useful as an optimization hint, since it can be applied only to local variables, and an optimizing compiler can see for itself that such an object's address isn't taken.

查看更多
登录 后发表回答