tags:

views:

239

answers:

9

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

A: 

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

EJP
Why is it a contradiction in terms? It might be silly, but theoretically, if a machine had enough registers to support something like this, it could work.
Avi
And it doesn't have enough registers. So it can't.
EJP
@EJB That still doesn't make it a contradiction in terms.
Simon
Of course it does. The 'register' modifier is a hint to the compiler that the variable should be held in a register for its life. Its life is defined as a method scope by the language: it can only be applied to a function parameter or within a block, which can only occur inside a method. Global variables persist beyond a method scope, again by definition. So it's a contradiction in terms.
EJP
@EJP: on a processor with 16 registers, I don't see that it "doesn't have enough registers" to spare one for a global variable, if that's what the programmer wants. I also don't see how it has anything to do with function scope. Registers are part of the hardware: they certainly stick around long enough for global scope. As far as I can tell, you've said "you can't apply `register` to a global because the standard says you can only apply it to automatic variables. This is a contradiction in terms." As caf explains, the practical problem motivating the standard is one of compilation scope.
Steve Jessop
OK, it's a contradiction in terms because the language specification mutually excludes them.
EJP
@EJP: So your answer to the question "why does the C language exclude global register variables" is "because the C language excludes global register variables". It's not very illuminating, is it?
JeremyP
-1 Some architectures have registers specifically made to be global (SPARC for example). There is no contradiction in terms.
Graphics Noob
@JeremyP, you are constructively misquoting the question to your own advantage here.
EJP
@EJP: I am changing the wording of the question, but I haven't changed the meaning. There's no contradiction in terms. The only contradiction in terms would be if registers only had local scope. On some architectures that may be true, but it is not generally the case.
JeremyP
I don't agree with any of this. I'm quite confident that if you asked Dennis Ritchie what is reason was he would say it was a contradiction in terms too. Remember he only had 8 registers on the PDP-11 including PC and SP. If he had wanted to restrict it to compilation units he could have done so, by allowing 'static'. He didn't.
EJP
I honestly believe that the question is asking for the motivation behind this restriction in the standard. I guess you honestly believe that it is not, but rather is just asking for confirmation that the standard does indeed dictate this?
Steve Jessop
I honestly believe it *is* a contradiction in terms and that DMR thought so too.
EJP
@EJB No it doesn't make it a contradiction in terms. What is it supposed to be contradicting? A register stores a value. There is no maximum length of time that a register can hold a value for (except for the obvious one of the CPU needs to be powered on). C runs on many different architectures than a PDP-11 nowadays and many of which have lots of registers (32 is quite common, a few have 64+).
Simon
Doh, no edit. 32 general purpose registers that is.
Simon
+3  A: 

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.

Philipp
Since when global variables are in the heap?
qrdl
-1 for saying that the `register` keyword is ignored, this is just wrong.
Jens Gustedt
@Jens: what modern compiler pays attention to the `register` keyword? As far as I know, gcc ignores it. (gcc also ignores `inline`).
R..
@R.: please see my answer. but in the mean time you could also try `register int i = 0; int *a = ` in function scope. Also for `inline` you are completely mistaken; it is a very important and usefull addition to C in C99.
Jens Gustedt
Indeed I wasn't precise enough. The `register` keyword doesn't force the compiler to place the object in a processor register, but all the other semantics stay intact.
Philipp
+5  A: 

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

adf88
The SPARC architecture has dedicated global registers which lend themselves to specifically that purpose, so I don't think it's right to call it "senseless." More like "impractical for a compiler to be able to implement across different architectures"
Graphics Noob
I agree with you.
adf88
+12  A: 

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

caf
+1, Yes, for example in a specific embedded system it can be obvious to want keep a permanently needed datum in a dedicated register. Pure C is not rich enough to fulfill that need.
Peter G.
+5  A: 

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:

Luther Blissett
+1  A: 

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.

Charlie
+1  A: 

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
Jens Gustedt
A: 

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.

supercat
A: 

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.

Matt J.
hmmm agreed.....
fahad