Why cant register variables be made global? - c

While reading from a site a read that you can not make a global variable of type register.Why is it so?
source:
http://publib.boulder.ibm.com/infocenter/lnxpcomp/v8v101/index.jsp?topic=/com.ibm.xlcpp8l.doc/language/ref/regdef.htm

In theory, you could allocate a processor register to a global scope variable - that register would simply have to remain allocated to that variable for the whole life of the program.
However, C compilers don't generally get to see the entire program during the compile phase - the C standard was written so that each translation unit (roughly corresponding to each .c file) could be compiled independently of the others (with the compiled objects later linked into a program). This is why global scope register variables aren't allowed - when the compiler is compiling b.c, it has no way to know that there was a global variable allocated to a register in a.c (and that therefore functions in b.c must preserve the value in that register).

Actually, GCC allows this. A declaration in global scope in the form:
register int foo asm ("r12");
Allocates the register "r12" (on x86_64) for the global "foo". This has a number of limitations and the corresponding manual page is probably the best reference to all the hassle global register variables would make:
http://gcc.gnu.org/onlinedocs/gcc/Explicit-Reg-Vars.html

Because it would be senseless. Global variables exist all the time the application is working. There surely is no free processor register for such a long time ;)

The register keyword has a different meaning than what its name seems to indicate, nowadays it has not much to do with a register of the processing environment. (Although it probably once was chosen for this.) The only text that constrains the use of a variable that is declared with register is this
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
So it implements a restriction to automatic variables (those that you declare in a function) such that it is an error to take the address of such a variable. The idea then is that the compiler may represent this variable in whatever way pleases, as a register or as an immediate assembler value etc. You as a programmer promise that you wouldn't take an address of it. Usually this makes not much sense for global variables (they have an address, anyhow).
To summarize:
No, the register keyword is not
ignored.
Yes, it can only be used for stack
variables if you want to be standard conformant

Originally, register variables were meant to be stored in processor registers, but global variables have to be stored in the data or the BSS section to be accessible from every function. Today, compilers don't interpret the register storage class strictly, so it remains largely for compatibility reasons.

The register word is used in C/C++ as request to the compiler to use registers of processor like variables. A register is a sort of variable used by CPU, very very fast in access because it isn't located in memory (RAM). The use of a register is limited by the architecture and the size of the register itself (this mean that some could be just like memory pointers, other to load special debug values and so on).
The calling conventions used by C/C++ doesn't use general registers (EAX, EBX and so on in 80x86 Arch) to save parameters (But the returned value is stored in EAX), so you could declare a var like register making code faster.
If you ask to make it global you ask to reserve the register for all the code and all your source. This is impossible, so compiler give you an error, or simply make it a usual var stored in memory.

Some compilers provide a means of dedicating a register permanently to a variable. The register keyword, however, is insufficient. A compiler's decision to allocate the local variables for a routine in registers generally does not require coordination with anything in other source modules (while some development systems do register optimization between routines, it's far more common to simply define the calling convention so that all routines are allowed to freely alter certain registers (so a caller is responsible for saving the contents if they're needed after the function call) but must not alter others (so the called routine is responsible for saving and restoring the contents if the registers are needed in the function). Thus, a linker doesn't need to concern itself with register usage.
Such an approach is fine for local register variables, but useless for global ones. For global register variables to be useful, the programmer must generally tell the compiler which register is to be used for what variable, and make sure that such reservations are known to the compiler when compiling all modules--even those that don't use the register otherwise. This can be useful in embedded systems, especially with variables that are used by interrupts, but there's usually a very limited number (e.g. 2 or so) of such variables allowed in a system.

So do we all agree now? Do we all see that making a global variable a register variable would be a really, really bad idea? If the original C definition did not forbid it, it was probably because nobody thought anyone would actually implement it that way -- as they should not have especially back in CISC days.
Besides: modern optimizing compilers do a better job of deciding when to keep variables in registers than humans can do. If yours can't do it, then you really, REALLY need to get a better compiler.

Because they're in registers. It's a contradiction in terms.

Related

Is it useless to use the `register` keyword with modern compilers, when optimizing?

The C register keyword gives the compiler a hint to prefer storing a variable in a register rather than, say, on the stack. A compiler may ignore it if it likes. I understand that it's mostly-useless these days when you compile with optimization turned on, but is it entirely useless?
More specifically: For any combination of { gcc, clang, msvc } x { -Og, -O, -O2, -O3 }: Is register ignored when deciding whether to actually assign a register? And if not, are there cases in which it's useful enough to bother using it?
Notes:
I am not asking whether it the keyword any effect; of course it does - it prevents you from using the address of that variable; and if you don't optimize at all, it will make the difference between register assignment or memory assignment for your variable.
Answers for just one compiler / some of the above combinations are very welcome.
For GCC, register has had no effect on code generation at all, not even a hint, at all optimization levels, for all supported CPU architectures, for over a decade.
The reasons for this are largely historical. GCC 2.95 and older had two register allocators, one ("stupid") used when not optimizing, and one ("local, global, reload") used when optimizing. The "stupid" allocator did try to honor register, but the "local, global, reload" allocator completely ignored it. (I don't know what the original rationale for that design decision was; you'd have to ask Richard Kenner.) In version 3.0, the "stupid" allocator was scrapped in favor of adding a fast-and-sloppy mode to "local, global, reload". Nobody bothered to write the code to make that mode pay attention to register, so it doesn't.
As of this writing, the GCC devs are in the process of replacing "local, global, reload" with a new allocator called "IRA and LRA", but it, too, completely ignores register.
However, the (C-only) rule that you cannot take the address of a register variable is still enforced, and the keyword is used by the explicit register variable extension, which allows you to dedicate a specific register to a variable; this can be useful in programs that use a lot of inline assembly.
C Standard says:
(c11, 6.7.1p6) "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."
These suggestions being implementation-defined means the implementation must define the choices being made ((c11, J.3.8 Hints) "The extent to which suggestions made by using the register storage-class specifier are effective (6.7.1)").
Here is what the documentation of some popular C compilers says.
For gcc (source):
The register specifier affects code generation only in these ways:
When used as part of the register variable extension, see Explicit Register Variables.
When -O0 is in use, the compiler allocates distinct stack memory for all variables that do not have the register storage-class
specifier; if register is specified, the variable may have a
shorter lifespan than the code would indicate and may never be
placed in memory.
On some rare x86 targets, setjmp doesn’t save the registers in all circumstances. In those cases, GCC doesn’t allocate any
variables in registers unless they are marked register.
For IAR compiler for ARM (source):
Honoring the register keyword (6.7.1)
User requests for register variables are not honored
If an object of automatic storage duration never has its address taken, a compiler may safely assume that its value can only be observed or modified by code which uses it directly. In the absence of the register keyword, a compiler which generates code in single-pass fashion would have no way of knowing, given...
void test(int *somePointer)
{
int i;
for (int i=0; i<10; i+=2)
{
somePointer[i] = -1;
somePointer[i+1] = 2;
whether the write to somePointer[i] might possibly write i. If it could, then the compiler would be required to reload i when evaluating somePointer[i+1]. Applying the register keyword to i would allow even a single-pass compiler to avoid the reload because it would be entitled to assume that no valid pointer could hold a value derived from the address of i, and consequently there was no way that writing somePointer[i] could affect i.
The register keyword could be useful, even today, if it were not interpreted as imposing a constraint that the address of an object cannot be exposed to anything, but rather as inviting compilers to assume that no pointer derived from an object's address will be used outside the immediate context where the address was taken, and within contexts where the address is taken the object will be accessed only using pointers derived from address. Unfortunately, the only situations the Standard permits register qualifiers are those where an object's address is never neither used nor exported to outside code in any fashion--i.e. cases which a multi-pass compiler could identify by itself without need for the qualifier.
The register keyword could be useful, even with modern compilers, if it invited compilers to--at their leisure--treat any context where a register-qualified object's address is taken (e.g. get_integer(&i);) using the pattern:
{
int temp = i;
get_integer(&temp);
i = temp;
}
and to assume that a register-qualified object of external scope will only be accessed in contexts which either explicitly access the object or take its address. At present, compilers have very limited ability to cache global variables in registers across pointer accesses involving the same types; the register keyword could help with that except that compilers are required to treat as constraint violations all the situations where it could be useful.

Alternative to volatile?

I'm using a lot of volatile variables in my embedded firmware, but most of the time there is only one point in a function where I need to be sure the value is recent (at the start). But the rest of the function is referring to the same variable-name, and the value can be changed in the mean time, producing very unexpected code flow / results. I know this can be solved by using a temporary variable inside the function, but I was looking for a better solution.
Now I was wondering, instead of marking the whole variable as volatile, is there a way I could instruct the compiler (gcc) with a special keyword that I want to read the variable as if it was marked volatile, so I can use that keyword only once at the beginning of the function?
I'm a little confused about the scenario - if it's that you want one particular access to a variable to be treated as volatile, use
dest = *(volatile TYPE *)&src;
where TYPE is the type of src. You may also need
asm volatile ("" ::: "memory");
in carefully controlled locations, to prevent the compiler from moving loads/stores of other memory locations across the volatile read.
Also investigate C11's _Atomic types. (I'm not sure if GCC supports these yet.)
If your variable is in memory and your embedded system supports it you could use memory barriers. To make sure that nothing accesses the memory while you are reading the value out.

storage-class specifier 'register' in c99 semantics

I'm a foreigner reading C99, while a sentence (in 6.7.1) makes me confused:
'(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.'
How should I parse the second sentence :
The extent to, which such suggestions are effective, is implementation-defined.
The extent, to which such suggestions are effective, is implementation-defined.
which one is better?
Does that means an implementation has full powers to decide how to deal with register, even with a termination of translation?
Thanks.
Don't mix up register variables with registers of the CPU. These are not the same.
register has the purpose to allow for optimizations. Taking the address of a such a variable is forbidden and as a consequence such a variable can never alias, the compiler always masters its latest value. Thus it can realize such a variable easily as a CPU register or an assembler immediate, for example.
As a particular subcase there are const qualified register variables that can't be altered by the program directly nor behind the scenes by some other code that would access it through a pointer. Only such variables can easily be guaranteed to be constant through out the whole program execution.
No -- the extent to which the suggestions are effective, is implementation defined, but the effect of the code as a whole is not.
To put it slightly differently, when/if you put register into your code (where allowed), the compiler can completely ignore it -- and I feel obliged to add that nearly all reasonably modern compilers will.
Nonetheless, the mere presence of register won't prevent the code from compiling, unless you try to apply it somewhere it's not allowed (e.g., to a global variable).
Bottom line: don't use it, but don't worry about removing it from code that already has it either. It's a waste of time and effort, but with reasonably modern compilers a completely harmless one.
Register is an old keyword. Basically it is a hint to an optimizer telling that it is better to use register for storing this variable. The pharse that you are mentioning means that compiler can treat this hint in any way it wants. In our days of optimizing compilers, its meaning and value for 99% is nothing.

Register as a thread local variable

In gcc you can declare a thread local variable, for example, as shown below.
__thread long thread_local_variable;
Also, in gcc you can specify a variable to use a certain register, for example, as shown below.
long register_variable asm ("r15" );
I want to combine these two concepts, that is, I want to declare a thread local variable that uses a certain register. How can I do that?
You don't need to do anything special. Your example:
long register_variable asm ("r15" );
is already declaring a thread-local variable, merely due to the fact that each thread has its own set of register values.
There is no possible way to make GCC's global register-storage variables shareable between threads. The fact that this is not well documented speaks to how ill-thought-out and hackish the whole idea of register-storage global variables is...
If you think about it, that couldn't work.
For a thread local variable, each thread needs it's own instance of storage. There's only a single r15 register (or one per core. more precisely), so there's simply no place to put the storage for additional threads.
Also, to put it in GCC's documentation's terms:
The __thread specifier may be used alone, with the extern or static specifiers, but with no other storage class specifier.
the register keyword is a storage class specifier, so cannot be used with __thread.
When threads swap out, they typically save the entire register state of the processor onto a stack somewhere. When the thread is restored, the register state is read from memory back into the registers.
So, if the language you used allowed it then you could in theory make this work. Each thread would have its own copy of the r15 register while it was running. However...
GCC Thread storage just wasn't designed that way. It stores the data in RAM somewhere, so you can later pass the pointer to another thread if you want to.
If you think of it, you don't need anything special for it. register variables always have a lifetime that is the current invocation of the function in which they are defined. These always are "thread local" variables.
The gcc extension __thread and the C11 feature _Thread_local are completely different concepts. They specify that a variable of static storage is instantiated on a per thread base. These kind of variables are never register variables. The register keyword in C forbids you to take the address of a variable, and forces the variable otherwise to be similar to auto variables.

Volatile variable

Where is a volatile variable stored in the program memory (in which section)?
volatile is a type qualifier not a storage class specifier, so it does not determine storage location at all; it affects the definition of a variable's type, not its storage.
It simply forces the compiler to explicitly read a variable whose type is volatile from the variable's storage location (wherever that may be) rather than assuming that some previously read value in a register for example remains valid.
In C volatile just tells the compiler - "You don't have enough knowledge to assume the value of this variable hasn't changed". There is no "section" eg BSS, CSS for it.
Consider it a flag to the compiler to prevent certain types of optimisations. Its very handy in embedded programming, where memory at a certain address may "change" due to a hardware device input.
Here's a good explanation: http://www.embedded.com/columns/programmingpointers/174300478?_requestid=137658
The volatility of a variable does not change the place in which a variable is stored. What it changes is the semantics around how it is accessed with respect to reads and writes.
I do not believe the C standard says anything about the implementation of volatile. But typically, volatile guarantees release semantics for write operations on a variable and aquire semantics on read operations of a variable. This will not be true for every implementation though and you should read up on what your specific compiler guarantees
volatile has nothing to deal with storage class.
volatile just tells the compiler or force the compiler to "not to do the optimization" for that variable.
so compiler would not optimize the code for that variable and reading the value from the specified location, not through interal register which holds the previous value.
So, by declaring variable as volatile.. it gives garrantee that you will get the latest value, which may be alterred by an external event.
your code may be work fine if haven't declare that variable as volatile, but there may be chance of not getting correct value sometimes..
so to avoid that we should declare variable as volatile.
volatile is generally used when dealing with external events, like interrupts of hardware related pins.
example.
reading adc values.
const voltile means
you can not modify or alter the value of that variable in code. only external event can change the value.
controller pins are generally defines as volatile.
may be by declaring variable as volatile controller will do "read by pin" not "read by latch"... this is my assumtion. may be wrong...
but still there is lots of confusion when to choose variable as volatile..
A variable should be declared volatile whenever its value could change unexpectedly. In practice, only three types of variables could change:
Memory-mapped peripheral registers
Global variables modified by an interrupt service routine
Global variables within a multi-threaded application
Link : http://eetimes.com/discussion/beginner-s-corner/4023801/Introduction-to-the-Volatile-Keyword
So It is proffered to variable as volatile in such cases.
There's no reason for a volatile variable to be stored in any "special" section of memory. It is normally stored together with any other variables, including non-volatile ones. If some compiler decides to store volatile variables in some special section of memory - there's nothing to prevent it from doing so. But at the language level there's absolutely no reason for this.
Why are you asking such a question? What made you think that it should be stored in some special section of memory?
"Volatile" was used in C/C++ specifications to allow use of memory mapped devices. It directs the compiler not to optimize the variable defined with this keyword, just because the variable doesn't seem to change its state in compiler-visible code.

Resources