Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Static and global variable storage clarification

As I was reviewing memory organisation and storage in C/C++ I came upon this:

"Initialized data segment, usually called simply the Data Segment. A data segment is a portion of virtual address space of a program, which contains the global variables and static variables that are initialized by the programmer.

Note that, data segment is not read-only, since the values of the variables can be altered at run time."

(found in http://www.geeksforgeeks.org/memory-layout-of-c-program/ )

I was under the impression that a static and/or global variable remained immutable throughout an application, I thought this was the point of their existence. Can they really be altered at run time?

like image 978
AutomEng Avatar asked Mar 17 '23 18:03

AutomEng


2 Answers

Can they really be altered at run time?

Yes. Unless you declare them as const, of course.

I was under the impression that a static and/or global variable remained immutable throughout an application, I thought this was the point of their existence.

No, you're describing constants. Variables with so-called static storage duration have, how the name implies, a different lifetime. [basic.stc.static]:

All variables which do not have dynamic storage duration, do not have thread storage duration, and are not local have static storage duration. The storage for these entities shall last for the duration of the program (3.6.2, 3.6.3).

Just think about cout, a global stream object that you modify by inserting data into it.

like image 156
Columbo Avatar answered Mar 20 '23 07:03

Columbo


You'll generally find better documentation on a site that more people take an interest in updating, for example - from Wikipedia:

In computing, a data segment (often denoted .data) is a portion of an object file or the corresponding virtual address space of a program that contains initialized static variables, that is, global variables and static local variables. The size of this segment is determined by the size of the values in the program's source code, and does not change at run time.

The data segment is read-write, since the values of variables can be altered at run time. This is in contrast to the read-only data segment (rodata segment or .rodata), which contains static constants rather than variables; it also contrasts to the code segment, also known as the text segment, which is read-only on many architectures. Uninitialized data, both variables and constants, is instead in the BSS segment.

So, it's just a matter of definition:

  • the data segment holds the read-write variables

  • the "read only" data segment holds the constants

On some old/hockey systems they might not both with a read only data segment and just lump it all together - the main thing with the read only segment is that it means a few more bugs are reported more dramatically, rather than letting the program corrupt that data and potentially spew bogus results. That's probably why .data is general and sometime later - as OS/compiler writers had time and motivation to care - .rodata ended up being contrasted with it, but .data wasn't renamed to e.g. .rwdata. These names - .data, .rodata, test, BSS etc. were and are often used in assembly languages to denote where variables should be located.

As far as things go... global variables and static variables are similar in that the [possibly virtual] memory address for them - and indeed their total size - can typically be calculated (at least relative to some supporting CPU "segment" register that's left at a convenient value most of the time) at compile time. That's in contrast to automatic (stack) and dynamic (heap) variables, where the memory's transient. Most systems only have control over write-access to memory on a per-page basis (e.g. 4k, 8k), so it's far less practical to keep granting and removing write access to put transient const automatic and heap-based variables into memory that seems read-only to the process, and it's impractical when you consider the race conditions in a threaded application. That's why this whole distinction between read-write and read-only memory's normally discussed in the context of global and static variables.

like image 33
Tony Delroy Avatar answered Mar 20 '23 08:03

Tony Delroy