8

How does a compiler, C or C++, (for example, gcc) honors the const declaration?

For example, in the following code, how does the compiler keeps track that the variable ci is const and cannot be modified?

int
get_foo() {
    return 42;
}

void
test()
{
    int i = get_foo();
    i += 5;

    const int ci = get_foo();
    // ci += 7;  // compile error: assignment of read-only variable ?ci?
}
Arun
  • 19,750
  • 10
  • 51
  • 60

5 Answers5

13

Much like any other bit of symbol information for variables (address, type etc.). Usually there is a symbol table which stores information about declared identifiers, and this is consulted whenever it encounters another reference to the identifier.

(A more interesting question is whether this knowledge is only present during compilation or even during runtime. Most languages discard the symbol table after compiling, so you can manipulate the compiled code and force a new value even if the identifier was declared 'const'. It takes a sophisticated runtime system (and code signing) to prevent that.)

Kilian Foth
  • 13,904
  • 5
  • 39
  • 57
  • 1
    To add to this, a standard issue C++/C Compiler doesn't do much if anything to keep a variable like this "const" at run time, it just knows not to generate any code that could modify this value via the symbol table Kilian mentioned. Consequntly, some other compiler could create some code and if that code were loaded into the process, it could overwrite the memory at that location. That's bad. – Dlongnecker Oct 25 '11 at 17:28
  • 3
    Const data can be put inside a different block of memory and on some systems that block of memory will actually be marked as read-only. Much like the code itself resides in a different segment (perhaps the const data and code may be mixed). Of course this only applies to static consts and nothing created on the stack. – edA-qa mort-ora-y Oct 25 '11 at 17:31
5

Of course it is up the implementation of each compiler, but in a nutshell, it stores the variable's const and volatile qualifiers (if any) in its variable symbol table along with other information such as the variable's type and whether or not it is a pointer / reference.

Gabe
  • 84,912
  • 12
  • 139
  • 238
Michael Goldshteyn
  • 71,784
  • 24
  • 131
  • 181
2

As others have said, const is tracked by the compiler the same way the compiler tracks the fact that a variable is an int. In fact, I have read that at least gcc considers const int a distinct type from int, so it's not even tracked as a modifier, it's tracked the exact same way as an int.

Note that you actually can change the value of a const via pointer casting, but the result is undefined:

#include <stdio.h>
#include <stdlib.h>

int main(void) {
        const int c = 0;
        printf("%d\n", c);
        ++*(int*)&c;
        printf("%d\n", c);
}

On my machine using gcc, this prints

0
1

But compiling with g++ gives

0
0
Kevin
  • 53,822
  • 15
  • 101
  • 132
1

The compiler knows that ci is const because you told it so with the line

const int ci = get_foo();

As you pass ci around to other functions or assign it to other variables, the compiler preserves that const-ness by preventing you from doing anything that could potentially change its value.

For example, the following produces a compiler error.

int *ci2 = &ci;
(*ci2)++;

Because the compiler won't let you modify the value of ci.

Jack Edmonds
  • 31,931
  • 18
  • 65
  • 77
  • 1
    Your latter example should produce a compiler error even without the increment operation. One can't assign a pointer-to-const value to a pointer-to-non-const variable. – Phil Miller Oct 25 '11 at 20:10
1

I'm sure others can elaborate more, but in short, yes. The compiler keeps track of all type specifiers so that it knows that ci is of type "const int", and not "int".

JesperE
  • 63,317
  • 21
  • 138
  • 197