是一个与元素本身兼容的元素的结构

Is a struct of one element compatible with the element itself?

本文关键字:元素 结构 一个      更新时间:2023-10-16

如果我有以下结构:

struct Foo { int a; };

下面的代码是否符合C++标准?我的意思是,它不能产生一个"未定义的行为"吗?

Foo foo;
int ifoo;
foo = *reinterpret_cast<Foo*>(&ifoo);
void bar(int value);
bar(*reinterpret_cast<int*>(&foo));
auto fptr = static_cast<void(*)(...)>(&bar);
fptr(foo);

N3290中的9.2/20表示

一个指向标准布局结构对象的指针,使用interpret_cast进行适当转换,指向其初始成员(或者,如果该成员是位字段,则指向其所在的单元),反之亦然。

你的Foo是一个标准布局类。

所以你的第二个演员阵容是正确的。

我看不出第一个是正确的(我使用的架构中,字符的对齐限制比只包含字符的结构弱,在这种架构中,这会有问题)。标准的保证是,如果您有一个指向int的指针,它真正指向结构的第一个元素,那么您可以将其重新解释为指向该结构的指针。

同样,如果第三个是repret_cast,我看不出会定义什么(我很确定一些ABI使用不同的约定来传递结构和基本类型,所以这是非常可疑的,我需要在标准中明确提及才能接受它),我也很确定没有什么允许函数指针之间使用static_cast。

只要只访问结构的第一个元素,它就被认为是安全的,因为在结构的第一成员之前没有填充。事实上,例如,在Objecive-C运行时中使用了这种技巧,其中通用指针类型定义为:

typedef struct objc_object {
    Class isa;
} *id;

在运行时,真正的对象(仍然是裸露的结构指针)具有如下的内存布局:

struct {
    Class isa;
    int x; // random other data as instance variables
} *CustomObject;

并且运行时使用该方法访问实际对象的类。

Foo是一个简单的旧数据结构,这意味着它只包含您明确存储在其中的数据。因此,int和Foo的内存布局是相同的。

你可以毫无问题地从一个类型转换到另一个类型。使用这种东西是否明智是另一个问题。

PS:这种通常有效,但不一定是由于不同的对齐限制。请参阅A程序员的回答。