Const_cast of a static constant member

The following code compiles well with both GCC (4.2-4.6) and Clang (2.1), but when I run the executable, it gives me "Bus Error: 10". I do not understand the reason.

#include <iostream> struct A { static int const v; A() { ++*const_cast<int *>(&A::v); } }; int const A::v = 0; int main(int argc, char * argv[]) { A a, b, c; std::cout << av << std::endl; return 0; } 
+7
source share
7 answers

I think the corresponding quote is:

§ 7.1.6.1 (4) of N3242:

Except that any member of the class declared mutable can be modified, any attempt to modify the const object during its lifetime results in undefined.

The examples illustrate the point using const_cast . As James noted: a quote can be found in section 7.1.5 in the C ++ 03 standard.

A bit of work: this language rule allows the compiler to use read-only memory (if available in the target architecture) when something is declared const . Without this rule, const -ness could always be discarded without fear of any consequences, and using this would only be a matter of developer discipline. How can you at least tell people that they refer to UB, which is usually a good deterrent. const_cast itself is of secondary importance, since it doesn't matter how you trick the compiler into letting you manipulate the const object.

+12
source

5.2.11.7:

Depending on the type of object, a write operation through a pointer, lvalue, or a pointer to a data element obtained from const_cast which discards the state determinant) may cause undefined behavior (7.1.5.1)

In your case, you are trying to modify data that is in a read-only segment.

+6
source

Since you are not allowed to modify variables declared as const.

+4
source

I have no solution for the real problem. I can just say do not use const_cast unless the intent calls the const member function from the non-const member function, and const_cast is the result of const (to make it a mutable result for the non-const member function).

But I have a suggestion to improve your design:

 class A { private: static int v; public: A() { ++v; } static int get_v() { return v; } }; int A::v = 0; int main(int argc, char * argv[]) { A a, b, c; std::cout << a.get_v() << std::endl; return 0; } 
+2
source

Just because you chose const does not mean that you can write this memory.

All that const_cast<T> does is remove the variable constant from the compiler perspective. This allows the compiler to move forward and emit code to write to the variable. But at runtime, if the compiler / linker accidentally placed this variable in read-only memory, then the hardware will stop you writing there no matter how you produce it.

+2
source

Basically, if a variable is declared const, the compiler is allowed to print the results only in read-only memory. Taking a pointer / link to a const object, and then using const_cast to remove const can lead to undefined behavior.

In general, it is safe to use const_cast if the referenced object is not const (even if you have a const / pointer / link).

+2
source

The problem is this line:

 static int const v; 

Since you declared const, const_cast causes undefined behavior - in your case you are lucky to get a bus error (this is a segmentation error on my system).

Declare it non-constant, and you can call const_cast without any problems.

+1
source

All Articles