gpt4 book ai didi

c++ - nullptr volatile 读/写的副作用

转载 作者:行者123 更新时间:2023-12-05 01:03:23 25 4
gpt4 key购买 nike

我在看 this c++ lection(它是俄语)。16:10 左右,讲师提出了一个开放性问题:

拥有此代码:

int* foo()
{
volatile auto a = nullptr;
int* b = a;
return b;
}

int main()
{}

Clang 生成 the following foo (-Ofast)

的程序集
    mov     qword ptr [rsp - 8], 0 # volatile auto a = nullptr;
xor eax, eax
ret

意思是编译器假定从 a 读取没有副作用,并且基本上删除了 int* b = a; 部分代码。

另一方面,GCC generates有点不同的代码

    mov     QWORD PTR [rsp-8], 0 # volatile auto a = nullptr;
mov rax, QWORD PTR [rsp-8] # int* b = a;
xor eax, eax
ret

这里的编译器认为从 a 读取确实会产生副作用并保持一切原样。

问题是根据 C++20 标准的正确行为是什么?

最佳答案

a 的类型将是 volatile std::nullptr_t

std::nullptr_t 并不真正需要具有任何内部状态,尽管它被指定为具有与 void* 相同的大小。此类型仅指定转换行为。

std::nullptr_t 不需要在它占用的内存中存储一​​个值。所有转换行为仅取决于源具有 std::nullptr_t 类型这一事实。所以不需要在那里写入或读取 0 值。赋值 int* b = a; 不依赖于存储在 a 中的任何状态或值,仅依赖于其类型。

我会说这两种行为都是正确的。 volatile 访问的可观察副作用的确切含义是实现定义的,如果 std::nullptr_t 被实现为实际上不使用任何内存来存储值,那么无论如何都不会期望为初始化和 int* b = a; 中的隐式转换生成任何指令从/存储到它。但是如果 std::nullptr_t 的实现类似于始终具有值 0 的指针,那么期望存储和加载是合理的。

注意:答案最初声称 std::nullptr_t 可以在任意数量的存储字节中实现,这是错误的,因为标准要求 sizeof(std::nullptr_t) == sizeof(void*)。见 [basic.fundamental]/14 .


其实看了标准之后,我觉得GCC的行为比较可疑。至少根据 a note a 上的左值到右值转换不应该访问 nullptr_t glvalue。这意味着 a 的内存位置可能没有任何负载,因为它会引入该规则不应该出现的数据竞争的可能性。

关于c++ - nullptr volatile 读/写的副作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74353155/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com