C标准规定:
一个指向结构对象的指针,经过适当的转换,指向它的初始成员(或者如果该成员是位域,则指向它所在的单元),反之亦然。
如果所讨论的结构的第一个成员是匿名结构/联合,是否有任何可能(且定义明确)的方式在 C11 中执行这种“合适的强制转换”?或者如果包含的结构是匿名的,则执行“反之亦然”的反向转换?
我猜想强制转换为具有与匿名结构相同的成员序列的非匿名结构会使它的定义不明确,因为它们不兼容,因此不能保证具有相同的内存布局。
但是,C 标准规定:
此外,如果它们的标记和成员满足以下要求,则在单独的翻译单元中声明的两种结构、联合或枚举类型是兼容的:如果用标记声明了一个,则应用相同的标记声明另一个。如果两者都在各自翻译单元内的任何地方完成,则适用以下附加要求:其成员之间应存在一对一的通信<...>
我们可以尝试将此规则应用于匿名结构吗?假设我们有以下设置:
标头.h:
struct container {
struct {
int a;
char b;
};
};
void print(struct container *pcontainer);
sep.c:
#include <stdio.h>
#include "header.h"
void print(struct container *pcontainer){
printf("%d\n", ((struct { int a; char b; }*)pcontainer)->a);
}
主.c:
#include "header.h"
int main(void){
struct container container, *pcontainer;
pcontainer = &container;
pcontainer->a = 1;
print(pcontainer);
return 0;
}
(这在gcc (GCC) 4.8.3 20140911上编译并输出 1)。
考虑在print
函数内部的强制转换中使用的匿名结构,以及作为 的第一个成员的匿名struct container
结构main.c
。它们可以被视为“在单独的翻译单元中声明的类型”吗?此外,它们真的满足所有其他兼容性要求,还是我误解了什么?