2009-09-10 59 views
1

我目前正在使用Diab 4.4 C++编译器。这是一个总的POS,不符合ANSI标准,过去我发现它存在问题。retval = false && someFunction(); //是否调用someFunction()?

我想知道如果下面的问题是编译器的问题,或者在我的C++

知识的缺点我意识到,X = X & & y的形式;如果x是假的,将使y部分短路。编译器正在做的事情是在x = x & & y()的情况下短路。其中y()是一个非const函数。

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函数。如果它不是const,那么当retval为false时,编译器是否通过跳过A.someFunction()来超越它的界限?

此外,我认识到这个问题可以通过写入retval = A.someFunction()& & retval;但我真的很想知道为什么会发生这种情况。

回答

7

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

+0

没有意识到评价是懒惰的。现在更有意义。 – 2009-09-10 17:48:17

+0

...或使用&如果两个操作数都是/返回布尔值。 – RJFalconer 2009-12-31 15:55:22

10

短路适用于所有表达式,无论const -ness。跳过someFunction()的电话是正确的。

4

如果&&的第二个操作数是常量或不是那么重要。在第一个操作数计算结果为false之后,返回值是已知的,因此没有理由评估第二个操作数。

如果函数具有需要执行的副作用,请先放置它。

2

短路评估与const或非const无关。无论发生什么,都会发生。

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

+0

请注意,只有** && **表单是一个右值。你不能说:** C = if(A())B(); ** – NVRAM 2009-09-10 18:24:04

+0

是的,它更接近C = A()?除A()之外的A():B()被评估一次。 – MSalters 2009-09-11 10:11:35

+0

请记住,C在C中返回0或1,在C++中返回false或true。它不会返回任何一个操作数,除非它们的值为0或1,或者为false或true。 – 2009-09-11 13:58:10

1

该& &运算符也被称为快捷操作符,这意味着它只评估第二部分,如果第一部分返回true。这是& &和&之间的主要区别在于:

value = func1() && func2(); // evaluates func2() only if func1() returns true 

value = func1() & func2(); // evaluates both func1() and func2() 
+1

实际上,'&&'和'&'与仅有短路行为有很大不同。 '((0x10 && 0x01)== 1)'但是((0x10&0x01)== 0)'。 – 2009-09-10 18:18:24

+0

当然,我正在讨论评估布尔值。 – 2009-09-10 18:20:16

1

对于& &操作,

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

这样的情况下,第一var为0,编译器会计算表达式为0,毫无疑问,什么都X是。

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

+0

这并不能说明整个故事。当然编译器会这样做,如果表达式的左边部分可以静态地知道是真的还是假的。但是,此外,即使左手表达式复杂,也会在AT RUNTIME时发生。这是C++语言定义的一部分。 – 2009-09-10 22:58:05

+0

这也是不准确的。 1 && X不会返回X,除非X碰巧是一个布尔值。在C++中,&&返回true或false;在C中它返回0或1。 – 2009-09-11 13:59:17

5

正如其他人所说的那样,和& &总是执行短路评估。

还要注意的是短路计算可以非常有用,因为它可以让你写这样的代码:

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

没有短路评价,这将崩溃的一个NULL指针。

相关问题