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()
,但这并不意味着它必须在您的程序实际编译的硬件上这样做。
在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()
,但这并不意味着它必须在您的程序实际编译的硬件上这样做。