c++ if (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)) { ...}

或者&&可以改成||,调用还好吗?

在调用 func2 之前,

func1 将 return。如果 func1 return 为假,func2 将不会被调用。

|| 的情况下,如果 func1 return 为真,则不会调用 func2。这叫做短路。

是的,&&|| 的第一个操作数总是先求值。

仅在需要时根据第一个操作数的值计算第二个操作数;这有时被称为短路。对于 &&,仅当第一个为真时才调用;对于 ||,仅当第一个为假时。

是的,除了假设规则。

func1() && func2() 粗略表示if (func1()) return true; else return func2()!=false;(这里的return不是真正的"return",都是一个表达式,所以只是粗略)。 func1()?true:func2()更接近它的意思。

C++ 有短路规则。 && 首先评估左侧,如果 returns false 然后评估右侧。

但是,总有例外。

如果有人重写了两个参数的 &&,则在传递给 && 之前,双方都会进行评估。这是不覆盖 &&.

的一个很好的理由

其次,as-if 规则意味着编译器可以自由评估 func2() 如果这样做就像在 func1() 返回 true 时您没有这样做一样,如果当 func1() returns false 时,它的行为与调用 2nd 时的行为相同。也就是说,如果 func2() 的调用不可能是 "noticed"、 直到未定义的行为 .

这种事情的一个例子是严格的别名,其中 func1() 改变了一些值,func2() 没有定义的行为方式来检测它。但是 func2() 通过未定义的行为(例如,违反严格的别名)预计会检测到变化。

如果 func2()func1() 没有其他可证明的相互作用,并且没有副作用,那么 func2() 可以在 func1() 之前或之后在 as-if 下进行评估优化规则。这可能很有用,因为现代处理器一次可以做不止一件事(即使在一次 "thread" 执行中)。

如果实际上在之后进行了评估,func2()的结果可能会有所不同,但是由于该依赖性取决于未定义的行为,因此允许编译器计时-旅行却没有得到你期望的结果。

总而言之,将 C++ 理解为可移植汇编是不够的。因此,虽然在 C++ 运行的抽象机中逻辑上必须在 func2() 之前调用 func1(),但这并不意味着它必须在您的程序实际编译的硬件上这样做。