1

I was thinking about the constness in C++, and the const_cast<> statement. I wrote the following code, expecting to get 40 as a result, to check how the language behaves for very bad designed code:

void change(const int *data) {
    int *x = const_cast<int *>(data);
    *x = 20;
}

int main(int, char **) {
    const int some_const = 10;
    change(&some_const);
    const int *p = &some_const;
    return *p + some_const;
}

I compile with zero optimizations the following way to ensure that there is no small caveat in the code:

g++ test.cc -Wall -ansi -pedantic -g -o test -O0

However, when I run the code, the return value turns out to be 30 (obtained from echo $?).

I run the program with GDB and disassembled it, showing that when the code calculates the return value, it adds the constant literal directly (in this case 0xa, i.e. 10):

0x0804840b <+0>:     push   %ebp
0x0804840c <+1>:     mov    %esp,%ebp
0x0804840e <+3>:     sub    $0x14,%esp
0x08048411 <+6>:     movl   $0xa,-0x8(%ebp)
0x08048418 <+13>:    lea    -0x8(%ebp),%eax
0x0804841b <+16>:    mov    %eax,(%esp)
0x0804841e <+19>:    call   0x80483f4 <change(int const*)>
0x08048423 <+24>:    lea    -0x8(%ebp),%eax
0x08048426 <+27>:    mov    %eax,-0x4(%ebp)
0x08048429 <+30>:    mov    -0x4(%ebp),%eax
0x0804842c <+33>:    mov    (%eax),%eax
0x0804842e <+35>:    add    $0xa,%eax
0x08048431 <+38>:    leave
0x08048432 <+39>:    ret

Is this a language inconsistency or a compile error?

EDIT: The reason for giving the calculated value as the return value of the program is to make the assembly code easier to read.

Samuel Navarro Lou
  • 1,168
  • 6
  • 17
  • 2
    Attempting to change a [const is undefined behavior](http://stackoverflow.com/q/22656734/1708801), there is no inconsistency, the programmer needs to prevent undefined behavior. Once there is undefined behavior your program becomes unpredictable. – Shafik Yaghmour Nov 07 '14 at 13:37
  • You told the compiler that `some_const` is not going to change, so it can store the value in a register, inline the value or do whatever it likes that turns out to still correctly execute the progam as long as `some_const` is not changed as you promised. But as you broke your promise to the compiler you get that undefined behaviour. Using `const_cast` to get rid of the constness is only save for values that were not originally declared `const`. – foobar Nov 07 '14 at 13:42
  • What gets me concerned is that the compiler did not even show a warning compiling under the most restrictive conditions. Would it be possible to keep minimal tracking of the const addresses? (maybe not exhaustively, but at least the const address is known and can be tracked). – Samuel Navarro Lou Nov 07 '14 at 13:55
  • @gdasamu using [fstanitized=undefined](http://stackoverflow.com/a/22700059/1708801) may catch it but honestly by using `const_cast` you are telling the compiler you know what you are doing. – Shafik Yaghmour Nov 07 '14 at 14:21

0 Answers0