【问题标题】:Assignment by product (multiplication assignment) with increment or decrement in C++? [duplicate]在 C++ 中按递增或递减的乘积赋值(乘法赋值)? [复制]
【发布时间】:2014-01-01 22:25:38
【问题描述】:

为什么我们得到两个 follow 语句的不同结果:

int x = 5;
x = x * x++;

输出为 26;而下一个示例返回 30,尽管它们是相同的?!

int x = 5;
x *= x++;

谢谢

【问题讨论】:

  • 这不是未定义的吗? (两个)
  • 两者都是未定义的行为。变量的存储值在序列点之间不得修改超过一次。
  • 未定义的行为 意味着,无论你期望什么,你都错了。 未定义的行为意味着,您没有任何正当理由期望任何特定结果。
  • @kuroi 不,这种行为确实是未定义的。 Implementation-defined是另外一个类,比如NULL宏是怎么定义的就是implementation-defined。
  • @llnspectable :你是对的。我太快回答这个问题了。我的错。

标签: c++ operators variable-assignment increment multiplication


【解决方案1】:

它们在 C++03 和 C++11 中都表现出未定义的行为。在 C++11 术语中,您不能对同一标量进行两次未排序的修改,也不能使用同一标量进行一次修改和一次值计算,否则您将出现未定义的行为。

x = x * x++;

在这种情况下,递增x(一种修改)与x 的其他两个值计算没有顺序。

x *= x++;

在这种情况下,递增x 与左侧的x 的值计算无关。

有关未定义行为的含义,请参阅 C++11 §1.3.24:

未定义的行为
本国际标准没有要求的行为

【讨论】:

  • “递增x是无序的”x的修改对于其他两个值计算是无序的。 (在x++的值计算之后排序。)
  • 我只是想知道,未定义而不仅仅是未指定的评估顺序的原因是什么?
  • @user2345215 我相当确定它允许编译器在假设程序员不这样做的情况下执行优化。不过,其他人可能会有更好的答案。
  • 编译器应该让一些操作同时运行(在不同的 CPU 内核上)。当 2 个内核同时读取和写入同一个变量时,硬件可能会做一些奇怪的事情(例如生成垃圾或抛出异常)。由于 UB 允许做这些事情,编译器在决定如何进行并行化时不必担心。
【解决方案2】:

将 ++'d 值分配给原始值是未定义的行为。因此,分配一个 ++'d 然后相乘的值也未定义是有道理的。

【讨论】:

    猜你喜欢
    • 2012-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-08
    • 2020-06-12
    • 1970-01-01
    • 1970-01-01
    • 2012-01-22
    相关资源
    最近更新 更多