强制转换/赋值中的结构类型不兼容?
这是此问题的后续问题。
我试图避免使用显式 typedef 通过这样的强制转换将一个数组复制到另一个数组:
#include <stdio.h>
int main(void)
{
int i;
int dst[] = { 10, 20, 30 }, src[] = { 1, 2, 3 };
*(struct{int _[3];}*)dst = *(struct{int _[3];}*)src;
for (i = 0; i < 3; i++) printf("%d\n", dst[i]);
return 0;
}
使用 gcc,我收到 arrcpy.c:8: error: incomplete types in assignment< /code>,但是使用 Open Watcom 可以很好地编译(并且按我的预期工作,打印 1 到 3)。
gcc 的行为是否符合标准?如果是,相关章节是什么?我不明白为什么两个相同的类型定义 struct{int _[3];}
在 gcc 眼中不相同(或兼容)。
编辑:我很清楚这是一种糟糕的编码风格。问题是关于另一件事。我很好奇海湾合作委员会的行为背后是否有逻辑依据,是否合法。
This is a follow-up to this question.
I'm trying to avoid using an explicit typedef to copy one array to another through casts like this:
#include <stdio.h>
int main(void)
{
int i;
int dst[] = { 10, 20, 30 }, src[] = { 1, 2, 3 };
*(struct{int _[3];}*)dst = *(struct{int _[3];}*)src;
for (i = 0; i < 3; i++) printf("%d\n", dst[i]);
return 0;
}
With gcc I'm getting arrcpy.c:8: error: incompatible types in assignment
, however with Open Watcom it compiles fine (and works as I expect it, printing 1 through 3).
Is the gcc's behavior per the standard or not? If it is, what's the relevant chapter and section? I can't understand why two identical type definitions struct{int _[3];}
aren't the same (or compatible) in the gcc's eyes.
EDIT: I know full well it's a bad coding style. The question is about a different thing. I'm curious if there's a logical rationale behind the gcc's behavior, if it's legit.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
为什么不直接使用memcpy呢?
或者对于大小,而不是 3:
sizeof(dst)/sizeof(dst[0])
编辑:根据您的编辑,我只能假设,与 outis的答案,编译器看到两个结构定义就是两种不同类型的结构。尽管它们可能包含相同的数据,但它们是两种不同的类型。
Why wouldn't you just use
memcpy
?or for the size, instead of 3:
sizeof(dst)/sizeof(dst[0])
EDIT: With your edit, I can only assume that, as with outis' answer, the compiler sees the two struct definitions as just that, two different types of structs. Even though they may contain the same data, they're two different types.
基本上,类型等价不是 C 中的结构等价。 C 使用 主格类型系统。
根据 C99 § 6.7.2.1-7:
struct-declaration-list
和struct-or-union-specifier
来自 C 语法 (§ 6.7.2.1):即使两个不同的结构具有相同的内存布局,它们也是不同的类型。
如果要避免污染全局命名空间,可以在使用该结构的函数中本地声明该结构。
Basically, type equivalence isn't structural equivalence in C. C uses a nominative type system.
According to § 6.7.2.1-7 of C99:
struct-declaration-list
andstruct-or-union-specifier
come from the C grammar (§ 6.7.2.1):Even if two different structs have the same memory layout, they are different types.
If you want to avoid polluting the global namespace, you can declare the struct locally to the function in which you use it.
gcc 的行为是正确的,类型是两个不相关的未命名结构。这些结构中的每一个虽然具有相同的内存布局,但具有不同的名称。如果您确实想这样做,请使用 typedef。
The gcc behavior is right, the types are two unrelated unnamed structures. Each of those structs, while having the same memory layout, have different names. If you really want to do that, then use a typedef.
这两个 struct 定义不兼容:
从 C99 6.2.7 开始:
类型不相同。然而,如果它们在单独的翻译单元中声明,它们将是兼容的。
但是,即使它们兼容,您的代码仍然会调用未定义的行为,至少有两个原因:
The two
struct
definitions are not compatible:From C99 6.2.7:
The types aren't the same. If they were declared in separate translation units, they would be compatible, however.
However, even if they were compatible, your code would still invoke undefined behavior, for at least two reasons: