代码之家  ›  专栏  ›  技术社区  ›  Mike Lewis

retval=false&&someFunction();//是否调用someFunction()?

c++
  •  1
  • Mike Lewis  · 技术社区  · 15 年前

    我目前正在与DIABC 4.4 C++编译器一起工作。它是一个完全的POS,不符合ANSI标准,我在过去发现过它的问题。

    我想知道下面的问题是否是编译器的问题,还是我对C++的一个缺点?

    我认识到,如果x为假,x=x&y的形式将使y部分短路。编译器所做的是在x=x&y()的情况下进行短路,其中y()是一个非常量函数。

    class A
    {
    int _a;
    A(int a) { _a = a; }
    bool someFunction() { _a = 0; return true; } 
    };
    
    main(...)
    {
    A obj = A(1);
    bool retval = false;
    
    retval = retval && A.someFunction();
    
    /* What is the value of A._a here? */
    }
    

    我觉得不对的是编译器正在短路,即使somefunction()不是常量函数。如果不是const,那么当retval为false时,编译器是否跳过.someFunction()而越界?

    另外,我意识到写retval=A.someFunction()&&retval;可以避免这个问题,但我真的想知道为什么会发生这种情况。

    7 回复  |  直到 15 年前
        1
  •  7
  •   moonshadow    15 年前

    这个 && || 操作符被定义为懒惰地评估,这是语言的工作方式。如果希望副作用总是发生,请首先调用函数并存储结果,或者重构函数以从状态查询中分离工作。

        2
  •  10
  •   John Millikin    15 年前

    短路适用于所有表达式,无论 const -尼斯。跳过对的调用 someFunction() 是正确的。

        3
  •  5
  •   Josh Kelley    15 年前

    正如其他人解释的那样,和&始终执行短路评估。

    还要注意,短路评估可以 非常有用 ,因为它允许您这样编写代码:

    retval = obj_pointer && obj_pointer->SomeBooleanMethod();
    

    如果没有短路评估,这将在空指针上崩溃。

        4
  •  4
  •   Bill the Lizard Alexis MP    15 年前

    第二个操作数是否 && 是否为常量。在第一个操作数的计算结果为之后 false 返回值已知,因此没有理由计算第二个操作数。

    如果函数有需要执行的副作用,请将其放在第一位。

        5
  •  2
  •   David Thornley    15 年前

    短路评估与常数或非常数无关。不管怎样都会发生。

    声明 A() && B(); 会做什么 if (A()) B(); 是的(尽管它不是一个完美的替代品,因为第二个替代品允许 else )这有时用于将语句更改为表达式(例如在编写宏或将其嵌入另一语句时)。

        6
  •  1
  •   Philippe Leybaert    15 年前

    运算符也称为快捷运算符,这意味着只有当第一部分返回为真时,它才会计算第二部分。这是&和&之间的主要区别:

    value = func1() && func2(); // evaluates func2() only if func1() returns true
    
    value = func1() & func2(); // evaluates both func1() and func2()
    
        7
  •  1
  •   Learner    15 年前

    对于运营商,

    1 && X = X
    0 && X = 0
    

    因此,如果第一个var为0,编译器将把表达式的值定为0,毫无疑问,x是什么。

    编译器将忽略X部分,因为它不会影响结果。这里x可以是任何东西函数/变量/表达式…..