1

The other day, a C++ trainer said to me that "const" does have meaning only in compile time (statically) and thus doesn't have an influence in runtime... but when I test this example :

const int x = 5;
int * px = const_cast<int*>(&x);
*px = 10;
std::cout << "x = " << x <<std::endl; // x = 5 ???

x is not modified with 10 ! whereas, this example works as expected if we use pointers:

const int * x = new int(5);
int * px = const_cast<int*>(x);
*px = 10;
std::cout << "x = " << *x <<std::endl; // x = 10

So, this C++ trainer is wrong ?

Samidamaru
  • 1,061
  • 7
  • 18
Aminos
  • 754
  • 1
  • 20
  • 40
  • 1
    Example 1 is undefined behaviour whereas example 2 is completely well defined, if a bit evil. – Simple Dec 08 '15 at 16:28
  • 1
    `const` is only to enable the compiler to check you are not writing into something you shouldnt write into (because it is const). In the executable there is no `const`. – 463035818_is_not_an_ai Dec 08 '15 at 16:31
  • 1
    First case is undefined behavior [see this](http://stackoverflow.com/a/22656791/1708801) – Shafik Yaghmour Dec 08 '15 at 16:31
  • 1
    Other languages don't have to maintain compatibility with C. Not all C libraries are const correct, so `const_cast` is a necessary evil to interop with them. – Simple Dec 08 '15 at 16:35
  • 1
    @EricJ. that need 1 gigabyte of VM installed to start the most minimal "Hello world" app. – David Haim Dec 08 '15 at 16:36
  • 1
    @DavidHaim: That's an unfortunate, and generally incorrect/irrelevant bias. C# and Java *may* use more RAM than C/C++, and C/C++ *may* use more RAM than native assembly for a particular program. For embedded systems that can totally matter. For many applications, the additional RAM cost, if any, is far less than the cost to pay programmers to track down undefined behavior. – Eric J. Dec 08 '15 at 16:40
  • 1
    @EricJ. I talked about the physical size the VM takes on the hard disk, not the RAM cost, which is heavy. I personally believe that people who dedicate themselves to programing should program, and they should know about undefined behaviour. I don't believe spilling milliards of dollars to make some scripting kiddos happy that they can program desktop/mobile/server application "in their favorite language". but I guess we won't convince each others anyway – David Haim Dec 08 '15 at 16:52
  • 3
    @EricJ.: That a `NullPointerException` unwinding your stack is 100% defined behaviour does not usually help you much anyway. – Christian Hackl Dec 08 '15 at 16:52
  • @ChristianHackl: Every language has it's strengths and weaknesses. My point is to understand those and select the best language for the job at hand. Personally, I'll take that NullPointerException weakness of C# along with it's other weaknesses in most business applications (the class of app I work on most of the time). – Eric J. Dec 08 '15 at 17:11
  • Every statement about the behaviour of a C or C++ program implies "...if the program does not have undefined behaviour", unless explicitly stated otherwise. – M.M Dec 09 '15 at 05:03

3 Answers3

10

It's undefined behaviour to modify a const T via const_cast. This allows the compiler to optimise your code assuming it never happens. In your first code example, the compiler probably inserted a literal 5 in the code during the call to operator<<.

Your second example is completely well defined, because x is really pointing at an int, not a const int. In this case, casting away the constness is fine.

vsoftco
  • 55,410
  • 12
  • 139
  • 252
Simple
  • 13,992
  • 2
  • 47
  • 47
3

It is Undefined Behaviour to strip away constness of variable that was declared as const in the first place.

Stripping away const of a const pointer or reference to non const variable is fine, but is not recomended.

I can't think of any assembly directive that actually derived from the C++ const keyword, so I guess there is no "run-time" actions being done in this part, but , declaring a variable as const may signal the compiler to store the variable in the data segement, or hard-code the value inside the assembly code directly without allocating its neccesery space (on the stack etc.). so assembly code that derived from a const variable may be look completly different from assembly code that was derived from mutable variable.

David Haim
  • 25,446
  • 3
  • 44
  • 78
  • 1
    It's not UB to strip away constness, per se. The UB comes from writing to a const object. Example 1 is fully legal if `*px = 10;` is removed. – M.M Dec 09 '15 at 05:06
0

As other commenters mentioned it, you invoked undefined behaviour from the compiler by modifying an object which was originally declared const. const_castr is designed to strip away aquired constness, as when the object was declared modifiable, but than passed somewhere as const reference.

Your code actually borders on something else as well, which is also very dangerous. Have you defined your variable like this:

static const int x = 5;

You would also have a likely crash of your application. The reason for this is that variables declared like that are likely to be placed in read-only segment of the executable file, and modification to such a segement would cause a hardware abort.

SergeyA
  • 61,605
  • 5
  • 78
  • 137
  • `const_cast` may also be used to add in constness (and add or remove `volatile`-ity) – M.M Dec 09 '15 at 05:05