c++ - 正在同时修改指向的值和指针 UB

标签 c++ c language-lawyer undefined-behavior

我知道 C 和 C++ 以及不同的语言,但以下内容适用于两者。

TL/DR

我知道 i = i++; 是 UB,因为 i 在表达式中被修改了两次,而 C 和 C++ 禁止它。

引用资料:

C99 6.5 :

If a side effect on a scalar object is unsequenced relative to either a different side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. If there are multiple allowable orderings of the subexpressions of an expression, the behavior is undefined if such an unsequenced side effect occurs in any of the orderings

C++ 11 - 1.9 15 :

If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, and they are not potentially concurrent, the behavior is undefined.

所以我明白 *i = *i++ + *j++; 会导致 UB,因为在 i 上递增并影响 *i可能是无序的,CLang 在 C 或 C++ 模式下发出警告:warning: unsequenced modification and access to 'i' [-Wunsequenced] *i = *i++ + *j++;/em>

但我不理解 *i++ = *i + *j++; 上的相同警告。因为在这里,我们首先计算正确的部分,影响它,并在影响之后增加。

两种语言的规范都说(同一段,就在上面):

The value computations of the operands of an operator are sequenced before the value computation of the result of the operator

结束 TL/DR

所以问题是:

是这条线

*i++ = *i + *j++;

未定义的行为,或者 Clang(版本 3.4.1)在发出警告方面过于保守?

最佳答案

两者的原因

*i = *i++ + *j++;

*i++ = *i + *j++;

未定义是因为您正试图在一个表达式中使用指针 i,该表达式是一个值计算(解引用,*i)和一个具有副作用的表达式 (取消引用和递增,*i++),没有中间序列点。请记住 *i++ 被计算为 *(i++);您正在增加指针值,而不是所指向的东西。

关于c++ - 正在同时修改指向的值和指针 UB,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30379661/

相关文章:

c++ - 中断来自并行线程的阻塞调用

c++ - 可变参数模板 - 模棱两可的调用

c++ - 不受主存储器约束的函数所需的复杂性是多少?

c++ - 如何在 C++ 中重载 ofstream 运算符?

c++ - com 端口中的事件处理

每次使用 List 的方法后调用 C++ List 析构函数

c - C中文件获取内容

c - 如何将一个文本文件一点点分割成两个文件

c - 表达式的定义行为

c++ - 为什么允许我声明一个带有已删除析构函数的对象?