gpt4 book ai didi

c++ - 读取和比较 POD 类型的填充字节是未定义的行为吗?

转载 作者:IT老高 更新时间:2023-10-28 23:18:38 29 4
gpt4 key购买 nike

今天我遇到了一些大致类似于以下代码段的代码。 valgrindUndefinedBehaviorSanitizer 都检测到未初始化数据的读取。

template <typename T>
void foo(const T& x)
{
static_assert(std::is_pod_v<T> && sizeof(T) > 1);
auto p = reinterpret_cast<const char*>(&x);

std::size_t i = 1;
for(; i < sizeof(T); ++i)
{
if(p[i] != p[0]) { break; }
}

// ...
}

上述工具提示 p[i] != p[0] 比较时包含填充字节的对象已传递给 foo。示例:

struct obj { char c; int* i; };
foo(obj{'b', nullptr});

从 POD 类型中读取填充字节并将它们与其他内容进行比较是未定义的行为吗?我在 Standard 和 StackOverflow 上都找不到明确的答案。

最佳答案

您的程序的行为是定义的实现在两个方面:


1) 在 C++14 之前:由于 char 可能存在 1 的补码或有符号幅度 signed 类型,您可能 由于比较 +0 和 -0,返回一个令人惊讶的结果。

真正无懈可击的方法是使用 const unsigned char* 指针。这消除了对现已废除的(来自 C++14)1 的补码或有符号幅度 char 的任何担忧。


因为 (i) 您拥有内存,(ii) 您正在获取指向 x 的指针,并且 (iii) unsigned char 不能包含陷阱表示, (iv) charunsigned charsigned char 不受严格别名规则的约束,使用 const unsigned char* 来读取未初始化的内存是完美定义的。


2) 但是由于您不知道该未初始化内存中包含什么,因此读取它时的行为是未指定的,这意味着程序行为是实现定义的,因为 char 类型不能包含陷阱表示。

关于c++ - 读取和比较 POD 类型的填充字节是未定义的行为吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47437349/

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