[英]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
引發的異常Exception thrown at 0x00007FF7AB961478 in Sandbox.exe: 0xC0000005: Access violation writing location 0x00007FF7AB969C58
。
有沒有辦法讓 VS2019 的行為與 G++ 的行為相同? 以及如何使用 CMake 做到這一點?
以下所有標准參考均指N4659:2017 年 3 月后 Kona 工作草案/C++17 DIS 。
根據[dcl.type.cv]/4 的規定,您的程序具有未定義的行為
除了任何聲明為 mutable 的類成員都可以修改之外,任何在其生命周期內修改 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
因此, 惡魔可能會從你的鼻子里飛出來,除此之外對你的程序進行任何類型的分析,包括比較不同編譯器的行為,都將是徒勞的。
你的問題很有趣,似乎const_cast
將允許更改底層的const
對象,這確實很好,但不幸的是,不,即使它似乎正在工作,也不能以任何方式安全地更改const
對象。
const_cast
可以形成一個指向實際引用 const 對象的非常量類型的引用或指針,或者形成一個指向實際引用 volatile 對象的非 volatile 類型的引用或指針。 通過非常量訪問路徑修改常量對象並通過非易失性泛左值引用易失性對象會導致未定義行為。
你不應該試圖通過忽略這個問題來完成這項工作,我的猜測是你在調試模式下在 VS 中運行程序,所以它會捕獲 g++ 沒有的錯誤,但是如果你通過調試器運行你的程序,你會可能會看到同樣的問題,但不能保證未定義行為的性質。
要走的路是修復代碼,而不是忽略問題。
正如所指出的,您不能合法地修改 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
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.