【问题标题】:Does the placement of a pre-increment operator make a difference here?预增量运算符的放置在这里有什么不同吗?
【发布时间】:2015-10-07 09:33:59
【问题描述】:

在下面的 C++ 代码中,最后 xy 的值有区别吗?

const int LoopLength = 100;
unsigned short x = 0;
for (int i = 0; i < LoopLength; i++)
{
    x = ++x % 2;
    cout << x;
}

cout << endl;

unsigned short y = 0;
for (int i = 0; i < LoopLength; i++)
{
    ++y = y % 2;
    cout << y;
}

cout << endl << (x == y) << endl;

Coverity(静态分析工具)声称副作用发生的顺序未定义,如x = ++x % 2;。我不确定我是否应该担心。

【问题讨论】:

  • x 行还不错,但如果标准未定义顺序,则应将括号括在要首先发生的位上。然而,y 分配看起来像是一场等待发生的灾难。这甚至可以编译吗?
  • @underscore_d 由于斯蒂芬的链接答案规则,第一行应该定义明确。 preincrement 运算符返回一个可以赋值的glvalue,因此将它放在赋值运算符的左侧是非常好的语法。不过,我觉得围绕操作符的未定义排序会使整体行为未定义。
  • 谢谢 - 我只是在阅读解释为什么它可以产生有效的左值并回来编辑我的评论,但我为时已晚。每天都学习新东西 :) 我想我个人会避免它,除非我正在为 IOCCC 写东西!
  • @underscore_d 它编译 =/。我刚刚和一位同事谈过,他看到 y 线后不寒而栗。

标签: c++ pre-increment coverity


【解决方案1】:

这两种形式在 C++11 之前是完全未定义的,因为它们都写入相同的内存位置而没有中间的序列点。

根据链接的问题So why is i = ++i + 1 well-defined in C++11?,第一种形式在 C++11 中是合法的,因为写入的顺序更受限制。

我认为第二种情况没有很好地定义,因为没有指定对= 的操作数的评估顺序。

幸运的是,所有这些问题都可以通过永远编写几乎与此类似的代码来避免。你未来的代码维护者会感谢你并从未来给你送礼物。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-07-31
    • 1970-01-01
    • 2010-12-30
    • 1970-01-01
    • 2011-06-15
    • 1970-01-01
    • 2011-11-30
    相关资源
    最近更新 更多