Changing value of volatile const - G++ vs Visual Studio 2019

2

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?

c++
constants
g++
visual-studio-2019
volatile
asked on Stack Overflow Sep 11, 2020 by doomista • edited Sep 11, 2020 by anastaciu

3 Answers

4

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.

answered on Stack Overflow Sep 11, 2020 by dfri
1

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.

answered on Stack Overflow Sep 11, 2020 by anastaciu • edited Sep 11, 2020 by anastaciu
0

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).

answered on Stack Overflow Sep 11, 2020 by Jarod42

User contributions licensed under CC BY-SA 3.0