57

I wonder where constant variables are stored. Is it in the same memory area as global variables? Or is it on the stack?

rgettman
  • 167,281
  • 27
  • 248
  • 326

13 Answers13

46

How they are stored is an implementation detail (depends on the compiler).

For example, in the GCC compiler, on most machines, read-only variables, constants, and jump tables are placed in the text section.

Robert Harvey
  • 168,684
  • 43
  • 314
  • 475
  • 3
    This is probably the one true answer (though it would be more helpful to provide popular implementation methods after pointing this out.) – Lee B Oct 16 '09 at 06:54
  • Simply stating "implementation detail", while correct, may not be the "best" answer here. I would guess were dealing with a curious beginner, and as such, the challenge here is figuring out, and replying, "I think you meant to ask *this* and, as such, I think you want to read *that*". – Mizipzor Oct 16 '09 at 07:02
  • 1
    @Lee: If it's "implementation defined", any relying on "popular implementation methods" means your code might break on the next compiler update. Sadly enough, this is not understood by all, so many of those who do understand don't "provide" information on particular implementations, in hopes that the non-understanding types get the hint... – DevSolar Oct 16 '09 at 13:44
  • 3
    Sometimes it's not stored as data, but as code. I.e. instead of creating an int in any text or data segment to read from, it just uses an instruction to load the constant into a register. This is smaller and faster than loading an address into a register and then reading the data from the address stored. This is not necessarily done for arrays however, that can depend on compiler switches. – Adrian May 10 '13 at 12:55
  • Agree with @Adrian, in fact, for PIC32 microcontrollers, it stores in Flash/Program memory. – pluto Dec 18 '15 at 23:26
36

Depending on the data segmentation that a particular processor follows, we have five segments:

  1. Code Segment - Stores only code, ROM
  2. BSS (or Block Started by Symbol) Data segment - Stores initialised global and static variables
  3. Stack segment - stores all the local variables and other informations regarding function return address etc
  4. Heap segment - all dynamic allocations happens here
  5. Data BSS (or Block Started by Symbol) segment - stores uninitialised global and static variables

Note that the difference between the data and BSS segments is that the former stores initialized global and static variables and the later stores UNinitialised ones.

Now, Why am I talking about the data segmentation when I must be just telling where are the constant variables stored... there's a reason to it...

Every segment has a write protected region where all the constants are stored.

For example:

  • If I have a const int which is local variable, then it is stored in the write protected region of stack segment.
  • If I have a global that is initialised const var, then it is stored in the data segment.
  • If I have an uninitialised const var, then it is stored in the BSS segment...

To summarize, "const" is just a data QUALIFIER, which means that first the compiler has to decide which segment the variable has to be stored and then if the variable is a const, then it qualifies to be stored in the write protected region of that particular segment.

Jonathan Leffler
  • 666,971
  • 126
  • 813
  • 1,185
wrapperm
  • 1,196
  • 10
  • 18
  • 20
    "and if I have a global that is initialised const var, then it is stored in BSS and if I have an uninitialised const var, then it is stored in data segment..." ... I think it should be like unitialised -> bss , initialised -> data segment – Subbu Oct 12 '13 at 06:52
  • 4
    "if I have a const int which is local variable, then it is stored in the write protected region of stack segment". Which part of the stack is write protected? – jimis Dec 23 '13 at 17:34
  • 4
    Data Segment has 2 parts : Initialzed and unitialized. BSS ->uninitialized data segment. – Mayank Dec 09 '14 at 08:44
  • 4
    This answer has the bss and data segments swapped. The bss is described by a start address and a leg the and is used for zero-initialized or uninitialized variables, while the data segment is used for non-default initialized variables. – Jonathan Leffler May 04 '16 at 01:43
  • 2
    As @Jonathan Leffler mentions, the bss and data segments are swapped. Please correct this as it leads to confusion – Genís Aug 28 '16 at 10:33
  • "Code Segment - Stores only code, ROM" you mean MaskROM...? – Yousha Aleayoub Aug 22 '17 at 12:51
  • 1
    For better or worse, I've reversed the sense of BSS and data segments in this answer — with the main changes highlighted by strike-through and italics, but there were other consequential changes too. I don't think there's a write-protected region on the stack where constants are stored. I don't think there's a write-protected region on the heap where constants are stored. I'm not convinced there's a write-protected section in the BSS or data segments, either. – Jonathan Leffler Feb 22 '19 at 20:51
  • If you don't think there's a write-protected region on X, Y, Z. Why you state this in the answer as a fact? – Timur Fayzrakhmanov May 29 '19 at 06:47
12

Consider the code:

const int i = 0;
static const int k = 99;

int function(void)
{
    const int j = 37;
    totherfunc(&j);
    totherfunc(&i);
  //totherfunc(&k);
    return(j+3);
}

Generally, i can be stored in the text segment (it's a read-only variable with a fixed value). If it is not in the text segment, it will be stored beside the global variables. Given that it is initialized to zero, it might be in the 'bss' section (where zeroed variables are usually allocated) or in the 'data' section (where initialized variables are usually allocated).

If the compiler is convinced the k is unused (which it could be since it is local to a single file), it might not appear in the object code at all. If the call to totherfunc() that references k was not commented out, then k would have to be allocated an address somewhere - it would likely be in the same segment as i.

The constant (if it is a constant, is it still a variable?) j will most probably appear on the stack of a conventional C implementation. (If you were asking in the comp.std.c news group, someone would mention that the standard doesn't say that automatic variables appear on the stack; fortunately, SO isn't comp.std.c!)

Note that I forced the variables to appear because I passed them by reference - presumably to a function expecting a pointer to a constant integer. If the addresses were never taken, then j and k could be optimized out of the code altogether. To remove i, the compiler would have to know all the source code for the entire program - it is accessible in other translation units (source files), and so cannot as readily be removed. Doubly not if the program indulges in dynamic loading of shared libraries - one of those libraries might rely on that global variable.

(Stylistically - the variables i and j should have longer, more meaningful names; this is only an example!)

Jonathan Leffler
  • 666,971
  • 126
  • 813
  • 1,185
  • "(if it is a constant, is it still a variable?)" By definition, no. – Chris Lutz Oct 16 '09 at 07:25
  • 1
    `j` can surely be seen as a variable. The word "variable" is not defined in `C`, but in C++ `j` is a variable. `variable` is just a named object then, be it const or not. In C, literals and enumerators are called `constants` - i don't think that `j` is called a "constant" in C, also because it cannot appear in constant expressions. – Johannes Schaub - litb Nov 05 '09 at 15:37
4

Depends on your compiler, your system capabilities, your configuration while compiling.

gcc puts read-only constants on the .text section, unless instructed otherwise.

Michael Foukarakis
  • 35,789
  • 5
  • 74
  • 113
2

Usually they are stored in read-only data section (while global variables' section has write permissions). So, trying to modify constant by taking its address may result in access violation aka segfault.

But it depends on your hardware, OS and compiler really.

elder_george
  • 7,599
  • 19
  • 30
  • 2
    "So, trying to modify constant by taking its address may result in access violation aka segfault." Oh, if only that were true here on OS X. I just tested it, and it scarily works. – Chris Lutz Oct 16 '09 at 07:01
  • On Windows, e.g. it works only for some compilers. e.g. VC++ and gcc generate such code, but borland one's don't (at least they didn't last time I used them; things may have changed). – elder_george Oct 16 '09 at 07:33
  • When I try to modify global const variable, I get Access violation error (since variable stored in Read only data segment). But I am able to modify local const variable since variable stored in stack. – siva Oct 25 '15 at 18:14
2

offcourse not , because

1) bss segment stored non inilized variables it obviously another type is there.

       (I) large static and global and non constants and non initilaized variables it stored .BSS section.

       (II) second thing small static and global variables and non constants and non initilaized variables stored in .SBSS section this included in .BSS segment.

2) data segment is initlaized variables it has 3 types ,

      (I) large static and global and initlaized and non constants variables its stord in .DATA section.
      (II) small static and global and non constant and initilaized variables its stord in .SDATA1 sectiion.
     (III) small static and global and  constant and initilaized OR non initilaized variables its stord in .SDATA2 sectiion.

i mention above small and large means depents upon complier for example small means < than 8 bytes and large means > than 8 bytes and equal values.

but my doubt is local constant are where it will stroe??????

mohan
  • 21
  • 1
1

This is mostly an educated guess, but I'd say that constants are usually stored in the actual CPU instructions of your compiled program, as immediate data. So in other words, most instructions include space for the address to get data from, but if it's a constant, the space can hold the value itself.

Lee B
  • 2,097
  • 11
  • 16
0

Global and constant are two completely separated keywords. You can have one or the other, none or both.

Where your variable, then, is stored in memory depends on the configuration. Read up a bit on the heap and the stack, that will give you some knowledge to ask more (and if I may, better and more specific) questions.

Mizipzor
  • 45,705
  • 20
  • 92
  • 136
0

Some constants aren't even stored.

Consider the following code:

int x = foo();
x *= 2;

Chances are that the compiler will turn the multiplication into x = x+x; as that reduces the need to load the number 2 from memory.

Marc Dirven
  • 149
  • 1
  • 13
MSalters
  • 159,923
  • 8
  • 140
  • 320
  • ...or to a constant multiplication, where the 2 would be stored in the actual CPU instruction – Isak Savo Oct 16 '09 at 18:55
  • "Some constants arfen't even..." should be "aren't" (would have edited it but for some reason I can't make changes less than 6 characters :/ ) – Rptk99 Apr 11 '17 at 19:38
0

It may not be stored at all.

Consider some code like this:

#import<math.h>//import PI
double toRadian(int degree){
  return degree*PI*2/360.0;
}

This enables the programmer to gather the idea of what is going on, but the compiler can optimize away some of that, and most compilers do, by evaluating constant expressions at compile time, which means that the value PI may not be in the resulting program at all.

tomjen
  • 3,595
  • 3
  • 24
  • 35
0

Just as an an add on ,as you know that its during linking process the memory lay out of the final executable is decided .There is one more section called COMMON at which the common symbols from different input files are placed.This common section actually falls under the .bss section.

achoora
  • 1,190
  • 12
  • 28
0

I checked on x86_64 GNU/Linux system. By using pointer to 'const' variable, the value can be changed. I used objdump. Didn't find 'const' variable in text segment. 'const' variable is stored on stack. 'const' is a compiler directive in "C". The compiler throws error when it comes across a statement changing 'const' variable.

0

This is specific to Win32 systems.

enter image description here

harperville
  • 5,730
  • 7
  • 23
  • 32