C++ 一个元素的结构是否与元素本身兼容?

C++ 一个元素的结构是否与元素本身兼容?,c++,c++11,C++,C++11,如果我有以下结构: struct Foo { int a; }; 是符合C++标准的代码波纹管吗?我的意思是,它不能产生一种“未定义的行为”吗 Foo-Foo; int-ifoo; foo=*重新解释演员阵容(&ifoo); 空心条(int值); 条形图(*重新解释铸件(&foo)); 自动fptr=静态浇铸(&bar); fptr(foo); Foo是一个简单的旧数据结构,这意味着它只包含您明确存储在其中的数据。在本例中:一个int。 因此int和Foo的内存布局是相同的 您可以从一个类型转

如果我有以下结构:

struct Foo { int a; };

是符合C++标准的代码波纹管吗?我的意思是,它不能产生一种“未定义的行为”吗

Foo-Foo;
int-ifoo;
foo=*重新解释演员阵容(&ifoo);
空心条(int值);
条形图(*重新解释铸件(&foo));
自动fptr=静态浇铸(&bar);
fptr(foo);

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

您可以从一个类型转换到另一个类型,而不会出现问题。使用这种材料是否明智是另一个问题

附言:
通常有效,但不一定是由于不同的对齐限制。请参阅程序员的答案。

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

typedef struct objc_object {
    Class isa;
} *id;
在运行时,真实对象(仍然是裸结构指针)的内存布局如下:

struct {
    Class isa;
    int x; // random other data as instance variables
} *CustomObject;
运行时使用此方法访问实际对象的类。

N3290中的9.2/20说

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

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

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

我无法保证第一个是正确的(我使用的架构中,char的对齐限制比只包含char的struct弱,在这样的架构中,这是有问题的)。标准的保证是,如果您有一个指向int的指针,它实际上指向结构的第一个元素,那么您可以将它重新解释为指向结构的指针


同样,如果第三个是reinterpret_cast,我看不到任何东西会定义它(我很确定某些ABI使用不同的约定来传递结构和基本类型,因此这是非常可疑的,我需要在标准中明确提及以接受它)而且我很确定没有任何东西允许在指向函数的指针之间进行静态转换。

但是<代码>重新解释铸件?真的吗?@MrLister:reinterpret\u cast有什么问题吗?这正是针对这类东西的-将一件事重新解释为另一件事。标准要求指向POD结构的指针与其第一个元素的指针相同。-1由于对齐问题,答案不正确。请参阅编程人员的回答。该技术类似于旧Amiga中使用的技术。您在技术上是正确的,但您只回答了一半的问题。我非常确定结构可能比int有更严格的对齐要求,因此当您重新解释从
int
Foo
时,会遇到UB。我不确定另一种方式。这是否意味着struct不能比其初始成员进行更严格的对齐?如果是这样的话,这是否意味着指向struct的指针必须至少与char*一样宽?哦,对于唯一实际引用标准的答案,+1。@avakar,噢,我误读了第一个示例,我修复了我的答案。谢谢。两个重新解释的演员都很好。5.2.10-7表示这表现为一系列静态强制转换,如
static\u cast(static\u cast(&ifoo))
,对于标准布局类型,这是定义良好的。不要将铸造与
int*
混淆为某种程度上与铸造与
int
相关,后者的保证是完全不同的。@edA-qamort-ora-y,您忘记了“如果T2的对齐要求不比T1严格”部分。我想引证一个事实,即结构的对齐要求并不比其第一个成员的对齐要求更严格,即使它只是针对只有一个成员的结构的有限情况。(正如我所写的,这会使我使用的一些实现不一致;我很确定它以前是一致的,但是C++11有很多关于对齐的新文本,我可能错过了一个新的要求。)
struct {
    Class isa;
    int x; // random other data as instance variables
} *CustomObject;