H!

Could any one please tell me with some proper explanation for: Where dose Global, Static, Local, Register variables stored in memory?

Recommended Answers

All 6 Replies

The short answer: wherever the compiler and/or system choose to store them.

A longer answer follows.

Older systems used to make a distinction between "stack" and "heap" (e.g older IBM compatible PCs used different memory chips for "stack" and "heap", and needed special drivers to access heap). Global, static, and local variables were often stored in the stack, and dynamically allocated objects (eg created with malloc()) were often created in the heap.

These days, with modern 32 bit and 64 bit operating systems, there is no real distinction between "stack" and "heap". Accordingly, variables are stored in whatever memory makes sense.

Register variables are, in general terms, stored in machine registers. However machine registers are a relatively scarce resource, so compilers are smart in how they use them. So, if the register keyword is used in C/C++, the compiler may choose to ignore it, and allocate the variable like any other.

>Global, static, and local variables were often stored in the stack
Kinda sorta. An accurate description (as required by my standard nazi status) is that you essentially have three options: automatic, static, and dynamic. Automatic is pretty much always implemented using a runtime stack, which is why people talk about the stack, even though such an implementation isn't required. Static is generally implemented by storing the objects within the executable itself (you'll hear talk of data segments in the PC world) because they're of a known size and quantity. Finally, dynamic is implemented using an unspecified pool of memory doled out by interfaces such as malloc and operator new.

A more practical but less nazi answer is:

Global: If intialized, the data segment, otherwise the bss segment.
Static: Same as global.
Local: The runtime stack.
Register: Probably the runtime stack.

>Register variables are, in general terms, stored in machine registers.
In theory at least. Compiler writers learned quite quickly that the compiler is much better at allocating registers than the end programmer. More often than not, honoring requests for a register variable results in less optimized machine code, so compilers simply don't do it.

>if the register keyword is used in C/C++, the compiler may choose to ignore it
The compiler is extremely likely to ignore it. In fact, the register keyword is often compared to the auto keyword in terms of usefulness. Really the only difference you're likely to see when using register variables are added restrictions (eg. not being able to take the address in a well defined way).

As you say, Narue, my answer was what "kinda sorta" sometimes happens.

My shorter answer is the one I like for this type of question: completely accurate. But it, almost invariably, is not considered an answer to the question. Hence "kinda sorta" type answers come out of the woodwork. And standards nazis can drive a truck through the holes in such descriptions ;)

1000+1 fairy-tails about storage class specifiers and storage duration in C...

Older systems used to make a distinction between "stack" and "heap" (e.g older IBM compatible PCs used different memory chips for "stack" and "heap", and needed special drivers to access heap).

It was extended/expanded memory, not a heap. The heap never allocated in EMS/XMS. No special stack (or special heap) memory on x86 processors. A heap is a program artifact, not hardware feature...

Statics never "implemented by storing the objects within the executable itself" in PC world. All known loaders separated code and data segments in the memory.

Both auto and register specifiers specify "that the named object has automatic storage duration". Yet another quote from the language standard: "A register specifier has the same semantics as an auto specifier together with a hint to the implementation that the object so declared will be heavily used". The register keyword is not a restriction (it's possible to get address of register variable). It's a hint - that's all.

The original question lumps together two different notions: scope (global/others) and storage duration - "the property of an object that defines the minimum potential lifetime of the storage containing the object". Strictly speaking, it's unclear question, it's a question about the language implementation, not the language in itself.

So right short answer: in memory, of course, what a question!..

>Global, static, and local variables were often stored in the stack
Kinda sorta. An accurate description (as required by my standard nazi status) is that you essentially have three options: automatic, static, and dynamic. Automatic is pretty much always implemented using a runtime stack, which is why people talk about the stack, even though such an implementation isn't required. Static is generally implemented by storing the objects within the executable itself (you'll hear talk of data segments in the PC world) because they're of a known size and quantity. Finally, dynamic is implemented using an unspecified pool of memory doled out by interfaces such as malloc and operator new.

A more practical but less nazi answer is:

Global: If intialized, the data segment, otherwise the bss segment.
Static: Same as global.
Local: The runtime stack.
Register: Probably the runtime stack.

>Register variables are, in general terms, stored in machine registers.
In theory at least. Compiler writers learned quite quickly that the compiler is much better at allocating registers than the end programmer. More often than not, honoring requests for a register variable results in less optimized machine code, so compilers simply don't do it.

>if the register keyword is used in C/C++, the compiler may choose to ignore it
The compiler is extremely likely to ignore it. In fact, the register keyword is often compared to the auto keyword in terms of usefulness. Really the only difference you're likely to see when using register variables are added restrictions (eg. not being able to take the address in a well defined way).

.
.
.

>Global, static, and local variables were often stored in the stack
Kinda sorta.

...Kinda sorta....???

>Statics never "implemented by storing the objects within the executable itself" in PC world.
>All known loaders separated code and data segments in the memory.
I'm afraid you've said something nonsensical. I see two distinct flaws:

  1. You're mixing up the structure of an executable with the operation of a loader. My statement refers to the structure of an executable, with the intention of driving home the concept of static objects being separate from automatic objects.
  2. You're assuming I claimed that code and data are stored together in memory. I made no such statement or implication.

>The register keyword is not a restriction (it's possible to get address of register variable)
It's also possible to modify an object more than once between sequence points, but that's undefined too. It's possible to do a lot of things that are explicitly prohibited by the standard. C doesn't protect you from being stupid.

Since we're quoting the standard now (emphasis by me):

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.

FYI, when the standard says "shall", failure to meet the requirement is undefined. A footnote of the register storage class clauses explains further:

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 operator that can be applied to an array declared with storage-class specifier register is sizeof.

>It's a hint - that's all.
Yes, it's a hint. But it's a hint that introduces restrictions on the assumption that the hint is honored. Use of register silly these days because every modern compiler I'm familiar with refuses to honor the hint in all cases.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.