4

First, sorry for possible question redundancy.

Doing some little experiments with C/C++ pointers in GCC I encountered this somewhat weird behaviour when bypassing constantness of value at the pointer address.

#include <iostream>
int main()
{
    using namespace std;

    const double number = 100;
//bypassing constantess of pointed-to value
    double * pointer_to_value = (double *) &number;
    *pointer_to_value += 200;

    cout << "Adress of number: " << &number << "\tValue of number: " << number << endl <<
    "   Pointer value: " << pointer_to_value << "\tDereferencing pointer: " << *pointer_to_value;

    return 0;
}

I would expect both form of checking the value yielding same results. Location of value is same in both cases. Program generates following output, however:

Adress of number: 0x22ff30 Value of number: 100 Pointer value: 0x22ff30 Dereferencing pointer: 300

Anyone capable of explaining? Thanks in advance.

VarM
  • 49
  • 1
  • Check it out this -> "http://www.devx.com/tips/Tip/5508" – Mandar Pande Jun 13 '11 at 07:48
  • compile-time optimizations perhaps? – tidwall Jun 13 '11 at 07:48
  • @mandy - link should be http://www.devx.com/tips/Tip/5508 (without the quotes) – NotJarvis Jun 13 '11 at 07:55
  • you should use static_cast and dynamic_cast in c++. not the C cast operator as you did. – Stephane Rolland Jun 13 '11 at 08:33
  • possible duplicate of [changing const value in C](http://stackoverflow.com/questions/3709548/changing-const-value-in-c) – Bo Persson Jun 13 '11 at 09:19
  • @Stephane: `const_cast` in this case. – Mike Seymour Jun 13 '11 at 10:48
  • @Mike, no, static_cast<> in this case, which would have output a logically a compilation error since this code is a purely a bug in itself, or a dynamic_cast<> that would have safely returned a null pointer. On the contrarty, const_cast<> should be use only in rare rare times when one know that there is a non-const variable hidden behind... Promoting the use of const_cast is really not a good thing unless one really knows what is going behind. Obviously not the case here, since the compiler may really do what it wants with a const double declared on the heap. – Stephane Rolland Jun 13 '11 at 12:52

5 Answers5

10

It's undefined behaivor.

It's irrelevant why exactly it happens (actually because the compiler inlines the value).

Community
  • 1
  • 1
Yakov Galka
  • 70,775
  • 16
  • 139
  • 220
5

"UnConsting” const value via pointer is a Undefined Behavior.
So it is not posible to define a behavior not defined by the Standard.

Alok Save
  • 202,538
  • 53
  • 430
  • 533
1

Compiler optimization. Compiler doesn't expect you to try and trick it like that, it knows that the value is const, so it just cached it. Try to compile it without any optimization, and see if it makes any difference.

Generally the meaning of const is:

constant - the object shall not be modified. Attempt to do so results in undefined behavior. On most of the compilers it is compile-time error.

littleadv
  • 20,100
  • 2
  • 36
  • 50
0

Compiler optimization. You can overcome that by adding volatile keyword to the variable.

#include <iostream>
int main()
{
    using namespace std;

    volatile const double number = 100;
    //bypassing constantess of pointed-to value
    double * pointer_to_value = (double *) &number;
    *pointer_to_value += 200;

    cout << "Adress of number: " << &number << "\tValue of number: " << number << endl <<
    "   Pointer value: " << pointer_to_value << "\tDereferencing pointer: " << *pointer_to_value;

    return 0;
}
Xolve
  • 22,298
  • 21
  • 77
  • 125
  • 3
    Actually the way to overcome this problem is by not invoking undefined behavior in the first place. Like not trying to modify data that's originally `const`. – In silico Jun 13 '11 at 07:54
  • 3
    It's still undefined behavior. The compiler can put `number` into a read-only memory. – Yakov Galka Jun 13 '11 at 07:54
  • Very well agreed, one shouldn't even think of doing this. But this actually solves what (s)he *expected*. – Xolve Jun 14 '11 at 06:03
0

My guess is that gcc has done some optimizations on your behalf, replacing the reference to << number with << 100. Should be possible to verify by looking at the generated asm code.

Kaos
  • 984
  • 7
  • 17