相关疑难解决方法(0)

未定义的行为和序列点

什么是"序列点"?

未定义的行为和序列点之间的关系是什么?

我经常使用有趣和复杂的表达方式a[++i] = i;,让自己感觉更好.我为什么要停止使用它们?

如果您已阅读此内容,请务必访问后续问题重新加载未定义的行为和序列点.

(注意:这是Stack Overflow的C++常见问题解答的一个条目.如果你想批评在这种形式下提供常见问题解答的想法,那么发布所有这些的元数据的发布将是这样做的地方.这个问题在C++聊天室中受到监控,其中FAQ的想法一开始就出现了,所以你的答案很可能被那些提出想法的人阅读.)

c++ c++-faq undefined-behavior sequence-points

970
推荐指数
4
解决办法
10万
查看次数

带增量的 2 补码是否违反了 c++17 中的执行顺序规则,但不违反 c++14 中的执行规则?

这可能是“ 101”级别的问题,但有一些相关的痛苦,所以我会要求评论以保持自信。

我有一些遗留代码支持返回到及之前的这一行:

iTmp = ~iTmp++;
Run Code Online (Sandbox Code Playgroud)

在代码更改为之前,此方法 100% 有效。更改为后,它会计算出不同的值,但并非总是如此。这取决于该行在代码中的位置,是先执行 2 的补码还是先执行增量。

另外,如果您尝试强制使用括号,则会出现编译器错误:

iTmp = (~iTmp)++;

error C2105: '++' needs l-value
Run Code Online (Sandbox Code Playgroud)

这对我来说很有意义,因为 2 的补码结果不是中间变量,因此 ++ 没有任何可操作的内容。

我的研究告诉我

  1. 这是“”失败。
  2. 并不是这种情况下失败的主要原因。
  3. 二进制补码不是就地操作,因此它不会更改 iTmp,而是返回一个值。
  4. 遗留代码的工作靠运气 - 可能是由于编译器错误或错误总是强制执行运算符评估顺序。

我的评价正确吗?

对我来说,一个非常微妙的区别是前面的代码无效,但这一行可以:

if ( ++iTmp > 0)
Run Code Online (Sandbox Code Playgroud)

我没想到升级到会导致这个微妙的错误,但我不得不将代码更改为以下内容来解决问题:

iTmp = ~iTmp;
iTmp++;
Run Code Online (Sandbox Code Playgroud)

c++ order-of-execution c++14 c++17

1
推荐指数
1
解决办法
180
查看次数