在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)) { ...}
或者可能是&&可以更改为||,呼叫仍然是好的吗?
答案 0 :(得分:6)
是的,始终首先评估&&
和||
的第一个操作数。
第二个操作数仅在需要时根据第一个操作数的值进行评估;这有时被称为短路。对于&&
,只有在第一个为真的情况下才会调用它;对于||
,仅当第一个为假时。
答案 1 :(得分:2)
func1
将在调用func2
之前返回。如果func2
返回false,则不会调用func1
。
对于||
,如果func2
返回true,则不会调用func1
。这称为短路。
答案 2 :(得分:2)
是的,除了as-if规则。
func1() && func2()
大致意味着if (func1()) return true; else return func2()!=false;
(这里的return
不是真正的“返回”,而且它只是一个表达式,所以只是大致)。 func1()?true:func2()
更接近它的含义。
C ++有短路规则。 &&
首先评估左侧,然后如果它返回false
,则评估右侧。
但是,总有例外。
如果有人为这两个参数覆盖了&&
,则会在传递给&&
之前对双方进行评估。这是不能覆盖&&
的好理由。
其次,as-if规则意味着编译器可以自由地评估func2()
,如果这样做,那么当func1()
返回true
时你没有这样做,并且如果func1()
返回false
时,它的行为与 - 如果它被称为第二个相同。即,如果func2()
的调用无法被“注意到”,直到未定义的行为。
这种事情的一个例子是严格别名,其中func1()
会更改某些值,而func2()
没有定义的行为方式来检测它。但func2()
通过未定义的行为(比如违反严格别名)预计会发现变化。
如果func2()
与func1()
没有其他可互动的互动且没有副作用,那么func2()
可以在假设优化规则下func1()
之前或之后进行评估。这可能很有用,因为现代处理器一次可以执行多个操作(即使在执行的单个“线程”中)。
如果实际之后被评估过,func2()
的结果可能会有所不同,但由于该依赖性取决于未定义的行为,编译器可以进行时间旅行而不是结果你期望被生产。
它的长短是因为理解C ++就好像它是便携式组件是不够的。因此,虽然必须在func1()
之前在运行C ++的抽象机器中调用func2()
,但这并不意味着它必须在程序实际编译的硬件上执行此操作。