以下程序是 C 语言中严格符合的程序吗?我对 c90 和 c99 感兴趣,但 c11 的答案也可以接受。
#include <stdio.h>
#include <string.h>
struct S { int array[2]; };
int main () {
struct S a = { { 1, 2 } };
struct S b;
b = a;
if (memcmp(b.array, a.array, sizeof(b.array)) == 0) {
puts("ok");
}
return 0;
}
在对我在另一个问题中的回答的评论中,Eric Postpischil 坚持认为程序输出将根据平台而变化,主要是由于未初始化的填充位的可能性。我认为结构分配会覆盖所有位,b
使其与a
. 但是,C99 似乎没有提供这样的保证。从第 6.5.16.1 p2 节:
在简单赋值(
=
) 中,右操作数的值被转换为赋值表达式的类型,并替换存储在左操作数指定的对象中的值。
在复合类型的上下文中,“转换”和“替换”是什么意思?
最后,考虑同一个程序,除了 和 的定义a
是b
全局的。该程序会是一个严格遵守的程序吗?
编辑:只是想在这里总结一些讨论材料,而不是添加我自己的答案,因为我真的没有自己的创作。
- 该程序不严格符合。由于赋值是按值而不是按表示,因此
b.array
可能包含也可能不包含与a.array
. a
不需要转换,因为它与 的类型相同b
,但替换是按值,并且逐个成员完成。- 即使
a
和中的定义b
是全局的,后赋值b.array
也可能包含也可能不包含与 不同的位设置a.array
。(关于填充字节的讨论很少b
,但发布的问题不是关于结构比较。c99 没有提到如何在静态存储中初始化填充,但 c11 明确声明它是零初始化的。) - 附带说明一下,如果使用from初始化,
memcmp
则已明确定义。b
memcpy
a
我感谢所有参与讨论的人。