改变 volatile const 的值 - G++ vs Visual Studio 2019
Changing value of volatile const - G++ vs Visual Studio 2019
所以我有以下片段(背后有一个很好的理由):
#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;
}
在 G++ v8.2.0(来自 MinGW 套件)下,该程序可以正常编译并按预期输出 20
。在 VS2019 下,它编译,但抛出运行时异常 - Exception thrown at 0x00007FF7AB961478 in Sandbox.exe: 0xC0000005: Access violation writing location 0x00007FF7AB969C58
.
有没有办法让 VS2019 的行为与 G++ 的行为相同?以及如何使用 CMake 实现?
以下所有标准参考均指N4659: March 2017 post-Kona working draft/C++17 DIS.
根据 [dcl.type.cv]/4,您的程序有未定义的行为
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
因此,demons may fly out of your nose 以及超出这一点的任何类型的程序分析,包括比较不同编译器的行为,都将是徒劳的。
你的问题很有趣,似乎 const_cast
允许更改底层 const
对象,这确实很好,但不幸的是不, const
对象不能以任何方式安全更改,即使它看起来正在工作。
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.
你不应该试图通过忽略这个问题来解决这个问题,我的猜测是你在 VS 中以调试模式 运行 调试程序,所以它可以捕获 g++ 没有捕获到的错误,但是如果你 运行 你的程序通过调试器你可能会看到同样的问题,尽管根据未定义行为的性质不能保证它。
要走的路是修复代码,而不是忽略问题。
如前所述,您不能合法地修改 const 对象...
但是你可以在 non-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
)。
所以我有以下片段(背后有一个很好的理由):
#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;
}
在 G++ v8.2.0(来自 MinGW 套件)下,该程序可以正常编译并按预期输出 20
。在 VS2019 下,它编译,但抛出运行时异常 - Exception thrown at 0x00007FF7AB961478 in Sandbox.exe: 0xC0000005: Access violation writing location 0x00007FF7AB969C58
.
有没有办法让 VS2019 的行为与 G++ 的行为相同?以及如何使用 CMake 实现?
以下所有标准参考均指N4659: March 2017 post-Kona working draft/C++17 DIS.
根据 [dcl.type.cv]/4,您的程序有未定义的行为
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
因此,demons may fly out of your nose 以及超出这一点的任何类型的程序分析,包括比较不同编译器的行为,都将是徒劳的。
你的问题很有趣,似乎 const_cast
允许更改底层 const
对象,这确实很好,但不幸的是不, const
对象不能以任何方式安全更改,即使它看起来正在工作。
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.
你不应该试图通过忽略这个问题来解决这个问题,我的猜测是你在 VS 中以调试模式 运行 调试程序,所以它可以捕获 g++ 没有捕获到的错误,但是如果你 运行 你的程序通过调试器你可能会看到同样的问题,尽管根据未定义行为的性质不能保证它。
要走的路是修复代码,而不是忽略问题。
如前所述,您不能合法地修改 const 对象...
但是你可以在 non-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
)。