更改volatile const的值-G ++与Visual Studio 2019

问题描述

因此,我有以下代码段(及其背后的充分理由):

_

在G ++ v8.2.0(来自MinGW套件)下,该程序可以正常编译并按预期输出#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; } 。在VS2019下,它可以编译,但会引发运行时异常-20

是否有办法使VS2019的行为与G ++相同?以及如何使用CMake?

解决方法

以下所有标准参考文献均引用N4659: March 2017 post-Kona working draft/C++17 DIS


根据[dcl.type.cv]/4的规定,您的程序具有未定义的行为

除了任何声明为可变的类成员都可以修改之外,在其生存期内修改const对象的任何尝试都会导致未定义的行为。 [示例:

// ...

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

因此demons may fly out of your nose以及此后对程序的任何类型的分析(包括比较不同编译器的行为)将是徒劳的。

,

您的问题很有趣,看来const_cast可以允许更改基础的const对象,这确实不错,但不幸的是,const对象不能安全地更改无论如何,即使它似乎正在工作。

const_cast使得可以形成实际上指向const对象的非const类型的引用或指针,或者实际上指向易失性对象的非volatile类型的引用或指针。 通过非const访问路径修改const对象,并通过非易失性glvalue引用易失对象会导致不确定的行为

您不应尝试通过忽略问题来使此工作正常进行,我的猜测是您正在VS中以调试模式运行该程序,因此它会捕获g ++无法捕获的错误,但是如果您通过调试器运行程序您可能会遇到相同的问题,尽管根据未定义行为的性质不能保证。

解决方法是修复代码,而不是忽略问题。

,

请注意,您不能合法地修改const对象...

但是您可以在非const对象上使用const引用:

因此您可以使用以下内容:

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;
}

(也不需要volatile)。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...