gpt4 book ai didi

c++ - 空结构(或结构填充)可以有任意值吗?

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

假设我有这段带有 UB 的代码:

union Flag {
constexpr Flag() : empty{} {}

struct {} empty;
bool value;
};

static Flag flag;

int main() {
return flag.value;
}

UB 访问的位置 value当它不是 union 的活跃成员时Flag .

目前,UBSan 不会捕获此错误,因为(据我所知)UBSan 没有办法检查 union 的最后一个书面成员。对于这种特殊情况,我认为 UBSan 可以通过对 bool 类型的非真/假值进行相同的检查,间接捕获此处发生的一些 UB。如果一个空结构的字节被认为是“未初始化的”或“可以有任意值”,那么编译器可以合法地将这个空结构的任意字节设置为任何非零/一值,然后 UBSan 将能够捕获 bool 的无效值的负载。

我想知道的是:在语义上是否允许将空结构的标称字节——更一般地说,所有结构中的任何填充字节——初始化为任何非零模式?

最佳答案

Is it semantically permissible to have the nominal byte of empty structs–and more generally, any padding bytes in all structs–be initialized to any non-zero pattern?

就编译器而言,任何不属于类型值表示的字节都是公平游戏。好吧,在某种程度上。

您可以有效地将 memcpy 转换为此类字节,但这仅在源数据(直接或间接)来自该类型的现有对象时才有效。这来自 [basic.types]/2&3。因此,在对象模型中,用户无法将任何内容放入该存储空间。

因此,对于 C++ 对象模型中的代码,允许实现使用填充字节的内容。

C++20 的隐式对象创建规则使这变得更加困难,因为它允许未初始化的对象显示在已经有字节的存储中。这些表现通常与 placement-new 之类的代码无关,因此 UBSan 很难初始化这样的东西。

您展示的 union 是隐式生命周期(由于简单的复制/移动构造函数),因此用户可以玩这些东西。

关于c++ - 空结构(或结构填充)可以有任意值吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72654285/

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