为什么下面的代码会给出警告?
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;
…
}
现在 test
和 tp
引用相同的类型(一个是结构,一个是指向结构的指针),类似地 result
和result_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/