C++ 如果 (func1() && func2()),func1 是否必须在 func2 之前调用?
c++ if (func1() && func2()), does func1 have to be called before func2?
在C++中,如果我编写以下if语句。潜在的问题是什么?行为定义是否正确?谢谢
int i = 0;
// func1 will return the updated value for i.
// func2 will use the new value of i.
if (func1(i) && func2(i)) { ...}
或者可能是&;可以更改为||,呼叫仍然有效吗?
是,&&
和||
的第一个操作数总是首先求值。
第二个操作数仅在需要时根据第一个操作数的值进行求值;这有时被称为短路。对于&&
,只有当第一个为true时才调用它;对于||
,仅当第一个为假时。
是,除非符合"好像"规则。
func1() && func2()
大致意思是if (func1()) return true; else return func2()!=false;
(这里的return
不是真正的"返回",它都是一个表达式,所以只是大致意思(。func1()?true:func2()
更接近它的含义。
C++有短路规则。&&
首先评估左手边,然后如果返回false
,则评估右手边。
但是,总有例外。
如果有人为两个参数重写了&&
,那么在传递给&&
之前,将对双方进行评估。这是不覆盖&&
的一个很好的理由。
第二,假设规则意味着编译器可以自由地评估func2()
,如果这样做就像在func1()
返回true
时没有这样做一样,如果在func1()
返回false
时,它的行为就像调用2nd一样。即,如果无法"注意到"func2()
的调用,直至未定义的行为。
这类事情的一个例子是严格混叠,其中func1()
改变了一些值,而func2()
没有定义的行为方法来检测它。但func2()
通过未定义的行为(比如违反严格混叠(来检测变化。
如果func2()
与func1()
没有其他可证明的相互作用,并且没有副作用,那么func2()
可以在func1()
之前或之后根据假设优化规则进行评估。这可能很有用,因为现代处理器一次可以做不止一件事(即使是在单个执行"线程"中(。
如果实际上是在之后求值的,func2()
的结果可能会有所不同,但由于这种依赖关系取决于未定义的行为,编译器可以进行时间旅行,而不会产生您期望的结果。
总之,把C++理解为可移植程序集是不够的。因此,虽然在C++运行的抽象机器中,func1()
必须在func2()
之前进行逻辑调用,但这并不意味着它必须在程序实际编译的硬件上进行调用。
func1
将在调用func2
之前返回。如果func1
返回false,则不会调用func2
。
在||
的情况下,如果func1
返回true,则不会调用func2
。这被称为短路。