C - 不兼容的指针类型

标签 c pointers struct initialization incompatibletypeerror

为什么下面的代码会给出警告?

int main(void)
{
    struct {int x; int y;} test = {42, 1337};
    struct {int x; int y;} *test_ptr = &test;
}

结果:

warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
         struct {int x; int y;} *test_ptr = &test;
                                            ^

最佳答案

它们是两种匿名结构类型(它们都没有标签)。所有此类结构类型(在单个翻译单元中)都是不同的——它们永远不是同一类型。添加标签!

标准中的相关句子在§6.7.2.1 Structure and union specifiers:

¶8 The presence of a struct-declaration-list in a struct-or-union-specifier declares a new type, within a translation unit.

struct-declaration-list 是指类型中 {} 之间的 Material 。

这意味着在您的代码中,有两种不同的类型,一种用于每个 struct { … }。这两种类型是分开的;您不能正式地将一种类型的值赋给另一种类型,也不能创建指针等。事实上,您不能在分号之后再次引用这些类型。

这意味着你可以:

int main(void)
{
    struct {int x; int y;} test = {42, 1337}, *tp = &test;
    struct {int x; int y;} result, *result_ptr;
    result_ptr = &result;
    …
}

现在 testtp 引用相同的类型(一个是结构,一个是指向结构的指针),类似地 resultresult_ptr 指的是同一个类型,初始化和赋值都没问题,但是两种类型不同。不清楚您是否创建了任何一种类型的复合文字 — 您必须编写 (struct {int x; int y;}){.y = 9, .x = 8},但是struct-declaration-list 的存在意味着这是另一种新类型。

如评论中所述,还有§6.2.7 兼容类型和复合类型部分,其中说:

¶1 … Moreover, two structure, union, or enumerated types declared in separate translation units are compatible if their tags and members satisfy the following requirements: If one is declared with a tag, the other shall be declared with the same tag. If both are completed anywhere within their respective translation units, then the following additional requirements apply: there shall be a one-to-one correspondence between their members such that each pair of corresponding members are declared with compatible types; if one member of the pair is declared with an alignment specifier, the other is declared with an equivalent alignment specifier; and if one member of the pair is declared with a name, the other is declared with the same name. For two structures, corresponding members shall be declared in the same order. For two structures or unions, corresponding bit-fields shall have the same widths.

粗略地说,如果两个翻译单元(想想“源文件”加上包含的 header )中的类型定义相同,那么它们指的是相同的类型。感谢老天爷!否则,您将无法使用标准 I/O 库以及其他次要细节。

关于C - 不兼容的指针类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38298607/

相关文章:

c - fopen() 的问题

c - 有什么比用于彩票调度程序的 LCG 更好的(伪)随机数生成器?

c++ - 处理数组访问时可能会生成不一致的代码

c - 当程序具有打开的数据库连接时,可以替换 sqlite 文件吗?

c++ - C/C++,指针和函数的问题

c - 严格的别名规则真的是 "two-way street"吗?

c - 使用结构时,如何将以下汇编代码从编译器翻译成 C?

c - 我如何在 CFFI 中包装包含结构指针的结构?

c# - 另一个 PInvoke - 错误消息显示未找到源?

c - 如何防止使用UDP数据报的进程接收自己的消息?