相同的匿名结构是否兼容?

考虑这个代码片段:

#include <threads.h>

int thread_start(void *ptr)
{
    struct {
        int a;
        int b;
    } *data = ptr;

    return 0;
}

int main(int argc, char *argv[])
{
    struct {
        int a;
        int b;
    } data;

    thrd_t thread;
    thrd_create(&thread, thread_start, &data);
    thrd_join(thread, NULL);
    return 0;
}

关于 a void *to 的转换struct { int; int } *,假设匿名结构的字段与最初分配的结构的字段相同,根据 C 标准,这是定义明确的行为吗?

回答

如果这些结构不在同一个文件中,它们将是兼容的。

thread_start被在单独编译.c文件中定义(即一个单独的翻译单元),那么他们将是兼容。具体来说,成员的名称、类型和顺序是相同的,并且它们都具有相同的标签,在这种情况下是没有标签。

第§6.2.7¶1的的C标准规定了以下要求:

如果它们的类型相同,则两种类型具有兼容类型。用于确定两种类型是否兼容的附加规则在 6.7.2 中针对类型说明符、6.7.3 中针对类型限定符和 6.7.6 中针对声明符进行了描述。此外,在单独的翻译单元中声明的两个结构、联合或枚举类型 如果它们的标签和成员满足以下要求,则它们是兼容的: 如果一个用标签声明,另一个应用相同的标签声明。如果两者都在其各自的翻译单元内的任何地方完成,则适用以下附加要求:它们的成员之间应存在一一对应的关系,以便每一对对应成员都声明为兼容类型;如果对中的一个成员使用对齐说明符声明,则另一个成员使用等效对齐说明符声明;如果对中的一个成员使用名称声明,则另一个成员使用相同的名称声明。 对于两个结构体,相应的成员应以相同的顺序声明。对于两个结构或联合,相应的位域应具有相同的宽度。对于两个枚举,对应的成员应具有相同的值。

因此,如果这些结构不在同一个文件中,它们是兼容的。但是因为它们是,所以结构不兼容。

§6.7.2.1 ¶8说:

struct-or-union-specifier 中 struct-declaration-list 的存在声明了翻译单元内的新类型。

因此,第 6.7.2.1 节指定了单个翻译单元中发生的情况。当声明位于单独的翻译单元中时,§6.2.7 中的规范会覆盖 §6.7.2.1 中的规范。

注意:很容易混淆 6.2.7 和 6.7.2。

  • It kind of begs the question that if the two identical anonymous struct types are defined in translation unit "a", and another identical anonymous struct type is defined in translation unit "b", which one in "a" is compatible with the one in "b"?
  • @EugeneSh. I guess the way out of that can of worms is that ultimately it is objects that are being compared for type compatibility. So `struct { int a; int b; } foo;` in translation unit "a" would be compatible with `extern struct { int a; int b; } foo;` in translation unit "b", but neither is compatible with `struct {int a; int b; } bar;`. And also, `typedef struct { int a; int b } tfoo;` in translation unit "a" would be compatible with the identical type definition in translation unit "b".

以上是相同的匿名结构是否兼容?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>