赋值评估的顺序(我发现了我的第一个编译器错误吗?)

发布于 2024-08-23 19:02:20 字数 748 浏览 2 评论 0原文

这段代码有一个有趣的错误:

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”只是显示了一个错误?

我在第一个代码片段中找不到任何显示特定于实现的行为的内容;据我了解,后缀增量应该优先于赋值,并且赋值应该从右到左进行评估。第一个代码片段应该没有什么奇怪的,只是有点难以阅读。

This code has an interesting bug:

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)
    ;

For most compilers, the above code results in setting the "value" field of all structs in the respective arrays to 1.
However, for one specific compiler (let's call it xcc), the structs in struct_array1 are NOT initialized correctly. The "value" field is set to 0 for all structs, which kind of surprised me.

The following code snippet works as expected on all compilers:

for (i = 0; 
     i < sizeof(struct_array1) / sizeof(struct_array1[0]); 
     i++)
{
    struct_array1[i].value = struct_array2[i].value = 1;
}

Now, am I completely off here, or does the offending compiler "xcc" simply display a bug?

I can't find anything that displays implementation-specific behavior in the first code snippet; from what I understand the postfix incrementation should have precedence over the assignments, and the assignments should be evaluated right-to-left. There should be nothing wierd with the first code snippet, except that it's a tad unreadable.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

清风无影 2024-08-30 19:02:20

您调用了未定义的行为,因为它会修改 i 并出于计算新值以外的目的获取其值,而无需插入序列点。

C99标准的相关部分是第6.5节中的这一条款:

上一个序列和下一个序列之间
指向一个对象应该存储它的
值最多修改一次
表达式的求值。
此外,先验值应为
只读以确定要设置的值
已存储。

You have invoked undefined behaviour, because it modifies i and also fetches its value for a purpose other than calculating the new value, without an intervening sequence point.

The relevant part of the C99 standard is this clause in section 6.5:

Between the previous and next sequence
point an object shall have its stored
value modified at most once by the
evaluation of an expression.
Furthermore, the prior value shall be
read only to determine the value to be
stored.

长发绾君心 2024-08-30 19:02:20

struct_array1[i].value = struct_array2[i++].value = 1

我认为这是未定义的行为,因为 i++ 不能保证在下一个之前完成其所有副作用到达序列点。下一个序列点是语句末尾的“虚构”;。这是一个常见的陷阱,我认为您可以找到许多与之相关的主题,只需搜索序列点即可。

struct_array1[i].value = struct_array2[i++].value = 1

I think that's undefined behaviour because i++ is not guaranteed to complete all of its side-effects until the next sequence point is reached. The next sequence point is the 'imaginary' ; at the end of the statement. That's a common pitfall, I think you can find many topics on SO pertaining to it, just search for sequence points.

送你一个梦 2024-08-30 19:02:20

实际上,我们不应该在单一表达式中对同一变量执行多次求值

。如果我们这样做,这将是未定义的行为。

Actually we are not suppose to perform more than one evaluation for same variable, in signle

expression . If we do that thing, it will be undefined behaviour.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文