c++ - 复合条件表达式中的排序

标签 c++ logical-operators sequence-points

以下示例中的 if 语句来 self 正在尝试重新构建的旧项目。很抱歉,这不是一个可验证的示例,因为它不会重现错误,它可以自行编译。

enum S { };

struct R {
    S type, state;
    double height;
};

int main ()
{
    int rows;
    S alive, rc;
    double h;
    R *r, *n;

    // BEGIN
    if ( (((r = n-1)   ->type & rc) && h > r->height) ||
         (((r = n+1)   ->type & rc) && h > r->height) ||
         (((r = n-rows)->type & rc) && h > r->height) ||
         (((r = n+rows)->type & rc) && h > r->height) )
    {
        n->state = alive;
    }
    // END
}

但是,在项目中,使用相同的编译(clang 3.3 除了包含路径外没有其他选项),它给出了

warning: multiple unsequenced modifications to 'r' [-Wunsequenced]

(指向子表达式 r = n - 1)。 if 语句(标记在BEGIN-END 之间)在项目中是相同的,只是变量的类型可能不同。这里定义的类型只是粗略的近似值,但我认为它们与警告并不真正相关。我已经能够将表达式简化为

if( (r = n) || (r = n) ) //...

同时仍在项目中重现警告。

我的理解是,运算符&&||(未重载时)的第一个操作数求值后有一个序列点。所以我无法解释这个警告。

如果对表达式的形式有任何想法,而不考虑类型,那将会有所帮助。

编辑

使用 Vaughn Cato 的评论,我也发现了

if( ((r = n-1) ->type) || ((r = n+1) ->type) )

产生警告,同时

if( bool((r = n-1) ->type) || bool((r = n+1) ->type) )

没有。 S 实际上是一个模仿枚举的类,并且有一个自定义的底层类。它重载了按位运算符 &|! 用于屏蔽,以及隐式转换运算符到基础类型,在特定情况下是 大小_t。我不知道这有多大帮助,但很抱歉没有从一开始就披露更完整的信息。

最佳答案

参见 N3797 1.9/15

Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced.

5.14/2:(&& 运算符)
5.15/2:(|| 运算符)

If the second expression is evaluated, every value computation and side effect associated with the first expression is sequenced before every value computation and side effect associated with the second expression.

对“副作用”的引用意味着 r 的值顺序正确。

我的解读是这个警告是不正确的。表达式的顺序正确(不包括此处未显示的代码的任何奇怪效果)。

关于c++ - 复合条件表达式中的排序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22812475/

相关文章:

c++ - 这是在 C++03 中执行 "Expression SFINAE"的有效方法吗?

c++ - 依赖型自动扣除

c - C 中后置和前置增量运算符的奇怪行为

c++ - 对于全局常量,const 与#define 的主要优点是什么?

c++ - 缺少 Oracle 即时客户端头文件

javascript - Javascript 中的 XOR 运算符用于检查值

actionscript-3 - 如何将四叉树单元格的空间索引(二进制索引)转换为位置和维度值?

r - == 与公式的奇怪行为

c++ - 传递函数参数的求值顺序 - F1( int F2( int& x ), int x ) 的操作顺序

C++ 迭代器的无序修改