此代码有一个有趣的错误:
some_struct struct_array1[10] = {0};
some_struct struct_array2[10] = {0}
int i;
for (i = 0;
i < sizeof(struct_array1) / sizeof(struct_array1[0]);
struct_array1[i].value = struct_array2[i++].value = 1)
;
对于大多数编译器,上面的代码导致将各个数组中所有结构的“value”字段设置为1。 但是,对于一个特定的编译器(我们称之为xcc),struct_array1中的结构未正确初始化。对于所有结构,“value”字段设置为0,这让我感到惊讶。
以下代码段在所有编译器上按预期工作:
for (i = 0;
i < sizeof(struct_array1) / sizeof(struct_array1[0]);
i++)
{
struct_array1[i].value = struct_array2[i].value = 1;
}
现在,我完全离开这里,还是有问题的编译器“xcc”只显示错误?
我在第一个代码段中找不到任何显示特定于实现的行为的内容。根据我的理解,后缀增量应该优先于赋值,并且应该从右到左评估赋值。第一个代码片段应该没什么奇怪的,除了它有点不可读。
答案 0 :(得分:8)
您调用了未定义的行为,因为它修改了i
并且还为了计算新值以外的目的提取其值,而没有插入序列点。
C99标准的相关部分是第6.5节中的该条款:
在前一个和下一个序列之间 指向一个物体应该存储它 最多修改一次的值 表达的评价。 此外,先前的值应为 只读以确定要的值 存储
答案 1 :(得分:5)
struct_array1[i].value = struct_array2[i++].value = 1
我认为这是未定义的行为,因为i++
无法保证在到达下一个序列点之前完成所有副作用。下一个序列点是语句末尾的“虚构”;
。这是一个常见的陷阱,我认为你可以在SO上找到很多关于它的主题,只搜索序列点。
答案 2 :(得分:0)
实际上,我们并不认为在同一个变量中对同一个变量进行多次评估
表达。如果我们做那件事,它将是未定义的行为。