以下程序是 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则已明确定义。bmemcpya
我感谢所有参与讨论的人。