c++ - 结构对齐和类型重新解释

标签 c++ struct undefined-behavior

假设我有两种类型 A 和 B。

然后我做这个类型

struct Pair{
    A a;
    B b;
};

现在我有这样的功能。

void function(Pair& pair);

并假设 function 只会使用该对的 a 部分。

那么这样使用调用函数是不是未定义行为?

A a;
function(reinterpret_cast<Pair&>(a));

我知道编译器可能会在成员之后插入填充字节,但它也可以在第一个成员之前插入吗?

最佳答案

我认为这是定义的行为,假设 Pair 是标准布局。否则,它是未定义的行为。

首先,一个标准的布局类和它的第一个成员共享一个地址。 [basic.compound] 中的新措辞(澄清了之前的规则)如下:

Two objects a and b are pointer-interconvertible if:
* [...]
* one is a standard-layout class object and the other is the first non-static data member of that object, or, [...]
* [...]
If two objects are pointer-interconvertible, then they have the same address, and it is possible to obtain a pointer to one from a pointer to the other via a reinterpret_cast (5.2.10).

同样来自[class.mem]:

If a standard-layout class object has any non-static data members, its address is the same as the address of its first non-static data member. Otherwise, its address is the same as the address of its first base class subobject (if any).

所以从 APairreinterpret_cast 没问题。如果 function 只访问 a 对象,那么该访问定义明确,因为 A 的偏移量为 0,所以行为是相当于让 function 直接接受 A&。显然,对 b 的任何访问都是未定义的。


但是,虽然我相信代码是定义的行为,但这是个坏主意。它是 现在 定义的行为,但有一天可能有人会更改 function 以引用 pair.b,然后你就会陷入痛苦的世界。简单地写会容易得多:

void function(A& a) { ... }
void function(Pair& p) { function(p.a); }

然后直接用你的a调用函数

关于c++ - 结构对齐和类型重新解释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39599219/

相关文章:

c++ - For vs While 用于查找链表中的最后一项

c - 使用结构体指针的两个函数(读取和显示数组)

c++ - 指针/整数算术(未)定义的行为

c - 将带有 char* 字符串的 C 结构保存到文件中

c++ - lambda表达式移动捕获的时机

假设分母<>0,整数除法是否会溢出/下溢?

c++ - CopyMemory 复制比 VirtualAlloc 分配更多的字节怎么办

c++ - 类型名、类型成员和非类型成员 : is it valid code?

c++ - 如何从 Bison 行动访问类(class)成员

c - 初始化结构体中的数组