gpt4 book ai didi

c - a[a[0]] = 1 会产生未定义的行为吗?

转载 作者:太空狗 更新时间:2023-10-29 16:17:43 28 4
gpt4 key购买 nike

此 C99 代码是否会产生未定义的行为?

#include <stdio.h>

int main() {
int a[3] = {0, 0, 0};
a[a[0]] = 1;
printf("a[0] = %d\n", a[0]);
return 0;
}

在语句 a[a[0]] = 1; 中,a[0] 被读取和修改。

我看了 ISO/IEC 9899 的 n1124 草案。它说(在 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.

它没有提到读取一个对象来确定要修改的对象本身。因此,此语句可能会产生未定义的行为。

不过,我觉得很奇怪。这实际上会产生未定义的行为吗?

(我也想知道其他ISO C版本的这个问题。)

最佳答案

the prior value shall be read only to determine the value to be stored.

这有点含糊并引起混淆,这也是 C11 放弃它并引入新的排序模型的部分原因。

它想说的是:如果保证读取旧值的时间早于写入新值,那很好。否则就是UB。当然,要求在写入新值之前计算新值。

(当然,有些人会发现我刚才写的描述比标准文本更含糊!)

例如 x = x + 5 是正确的,因为在不知道 x 的情况下不可能计算出 x + 5。但是 a[i] = i++ 是错误的,因为不需要读取左侧的 i 来计算出要存储在 中的新值我。 (i的两次读取是分开考虑的)。


现在回到您的代码。我认为这是明确定义的行为,因为为确定数组索引而读取 a[0] 保证在写入之前发生。

在我们确定在哪里写之前,我们不能写。在我们读取a[0] 之前,我们不知道该写在哪里。因此读必须先于写,所以没有UB。

有人评论了序列点。在 C99 中,此表达式中没有序列点,因此不讨论序列点。

关于c - a[a[0]] = 1 会产生未定义的行为吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32152371/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com