【问题标题】:Difference between C++14 and C++17 using: `*p++ = *p`C++14 和 C++17 之间的区别使用:`*p++ = *p`
【发布时间】:2019-11-27 05:33:17
【问题描述】:

在编写一些代码时,我遇到了我设置的值设置错误的问题。我最终找到了罪魁祸首,在进行测试时发现它在 C++14 和 C++17 上的行为不同。代码如下:

#include <stdio.h>
#include <cstdint>
#include <cstring>

int main()
{
    uint8_t *p = new uint8_t[3];
    memset(p, 0x00, 1);
    p++;
    memset(p, 0xF0, 1);
    p++;
    memset(p, 0xFF, 1);
    p--;
    p--;

    // This line in particular
    *p++ = *p;

    *p++ = 0x0F;

    p--;
    p--;

    printf("Position 0 has value %u\n", *p);
    p++;
    printf("Position 1 has value %u\n", *p);
    p++;
    printf("Position 2 has value %u\n", *p);

    return 0;
}

在 C++14 上打印:

Position 0 has value 240
Position 1 has value 15
Position 2 has value 255

在 C++17 上它会打印:

Position 0 has value 0
Position 1 has value 15
Position 2 has value 255

我很好奇为什么它在不同的 C++ 版本上表现不同。看起来好像在 C++14 上,赋值右侧的 *p 是在 ++ 之后评估的。这改变了吗?而如果++ 有优先权,为什么不在赋值运算符左侧的解引用之前发生呢?

【问题讨论】:

  • 未指定您的代码是否编译,因为未指定 #include &lt;stdio.h&gt; 后跟 #include &lt;cstring&gt; 是否将名称 memset 置于全局范围内。
  • @L.F.我不明白你想说什么
  • @deW1 他们说 OP 包含 C++ &lt;cstring&gt; 但写了 C memset,并且可能无法使用某些工具链编译。 OP 想要&lt;string.h&gt;std::memset。 (在混合中添加盐是&lt;stdio.h&gt; 也可能会传递地引入memset!)

标签: c++ c++14 c++17


【解决方案1】:

读取和写入变量(通过后增量)曾经有未定义的行为,因为= 没有引入序列点。在 C++14 中,您可能会收到任何一种行为(或没有,或爆炸)。

Now, there is a sequencing order defined for this case 和您的 C++17 结果是可靠的。

虽然还是很烂,不清楚不应该写的代码!

【讨论】:

  • > 不应该编写的糟糕、不清楚的代码! 当然是糟糕的;顺序是错误的,与从左到右相反;我们不应该沉迷其中。
  • @Kaz 实际上,正确的优先评估是直观的。考虑CreateObject() = MayThrow() - 如果 RHS 抛出,您是否希望创建一个对象?不!
  • 请注意,链接中的示例与原始代码不同(尽管使用相同的标准引号),在i = i++(C++17 之前)中,增量与分配无关,但是在*p++ = *p 中,增量未使用正确的操作数值计算进行排序
猜你喜欢
  • 1970-01-01
  • 2017-03-28
  • 1970-01-01
  • 2011-03-11
  • 1970-01-01
  • 1970-01-01
  • 2018-03-16
  • 1970-01-01
  • 2021-01-05
相关资源
最近更新 更多