是否将未标记结构重新声明为兼容类型?

Eri*_*hil 9 c language-lawyer

出于此问题中表达的目的,我们希望这样做:

typedef struct { int a; } A;
typedef struct { struct { int a; }; int b; } B;

A *BToA(B *b) { return (A *) b; }
B *AToB(A *a) { return (B *) a; }
Run Code Online (Sandbox Code Playgroud)

希望是演员表符合C 2011 6.7.2.1 15,其中说"指向结构对象的指针,适当转换,指向其初始成员(或者如果该成员是位字段,则指向其中的单位)它居住),反之亦然."

由于struct { int a; }内部B没有名称,我们称之为A'.

"适当地"没有明确定义.我相信,如果A *是一个有效的指针类型的对象A',则(A *) b执行适当的转换,并且类似地,如果a是一个指针A'是一个B,则(B *) a是合适的转化.

所以问题是:是A *一个指向类型对象的有效指针A'吗?

6.7.6.1,A *是兼容A' *,如果A是兼容的A'.

根据6.2.7,"如果类型相同,则两种类型具有兼容类型...此外,如果它们的标记和成员满足以下要求,则在单独的翻译单元中声明的两个结构,联合或枚举类型是兼容的:如果声明了一个标签,另一个应使用相同的标签声明.如果两者都在其各自的翻译单元内的任何地方完成,则以下附加要求适用:其成员之间应存在一对一的对应关系,以便每对相应的成员被宣布为兼容类型; 如果使用对齐说明符声明该对中的一个成员,则使用等效的对齐说明符声明另一个成员; 如果该对的一个成员使用名称声明,则另一个成员使用相同的名称声明.对于两个结构,相应的成员应按相同的顺序申报......"

这些不能是6.7.2.3 5中的相同类型:"不包含标记的结构,联合或枚举类型的每个声明都声明了一个不同的类型."

由于它们不是同一类型,它们是否兼容?6.2.7中的文字说如果在单独的翻译单元中声明它们是兼容的,但它们在同一个翻译单元中.

M.M*_*M.M 1

正如您在问题中提出的那样,标准明确无误地表示struct { int a; }同一翻译单元中的两个结构定义声明了两种不兼容的类型。尽管事实上这可能是“奇怪的”。编译器始终遵循该标准

对我来说,这似乎是合理的行为:如果您的项目中碰巧有语义上不相关的结构,并且恰好有一个具有相同类型的成员列表,那么您确实希望编译器拒绝两者之间的意外分配。


关于。根据 6.7.2.1/13,您问题中的代码,

匿名结构或联合的成员被视为包含结构或联合的成员。

所以我将 的定义B视为等同于:

typedef struct { int a; int b; } B;
Run Code Online (Sandbox Code Playgroud)

以便进一步分析。