So I have a following snippet (and a good reason behind it):
#include <iostream>
volatile const float A = 10;
int main() {
volatile const float* ptr = &A;
float* safePtr = const_cast<float*>(ptr);
*safePtr = 20;
std::cout << A << std::endl;
return 0;
}
Under G++ v8.2.0 (from MinGW suite), this program compiles fine and outputs 20
as expected. Under VS2019, it compiles, but throws a runtime exception - Exception thrown at 0x00007FF7AB961478 in Sandbox.exe: 0xC0000005: Access violation writing location 0x00007FF7AB969C58
.
Is there a way to make VS2019 behave the same way the G++ does? And how to do it with CMake?
All standard references below refers to N4659: March 2017 post-Kona working draft/C++17 DIS.
As governed by [dcl.type.cv]/4, your program has undefined behaviour
Except that any class member declared mutable can be modified, any attempt to modify a const object during its lifetime results in undefined behavior. [ Example:
// ... const int* ciq = new const int (3); // initialized as required int* iq = const_cast<int*>(ciq); // cast required *iq = 4; // undefined: modifies a const object
and as such, demons may fly out of your nose and any kind of analysis of your program beyond this point, including comparison of the behaviour for different compilers, will be a fruitless exercise.
You question is interesting, it would seem that const_cast
would allow to change an underlying const
object, that would be nice indeed, but unfortunately no, const
objects cannot be safely changed by any means, even though it appears to be working.
const_cast
makes it possible to form a reference or pointer to non-const type that is actually referring to a const object or a reference or pointer to non-volatile type that is actually referring to a volatile object. Modifying a const object through a non-const access path and referring to a volatile object through a non-volatile glvalue results in undefined behavior.
You should not try to make this work by ignoring the problem, my guess is that you are running the program in VS in debug mode so it catches the error where g++ doesn't, but if you run your program through the debugger you'll likely see the same problem, though it's not guaranteed as per the nature of undefined behavior.
The way to go is to fix the code, not to ignore the problem.
As point out, you cannot legally modify const objects...
But you can have const reference on non-const object:
so you might use the following:
const float& A = *([]() { static float a = 10; return &a; }());
// const float& A = []() -> float& { static float a = 10; return a; }();
int main() {
float* safePtr = const_cast<float*>(&A);
*safePtr = 20;
std::cout << A << std::endl;
}
(No need of volatile
neither).
User contributions licensed under CC BY-SA 3.0