我正在观看CppCon视频,其中显示了以下代码:
void foo(const int&);
bool bar(int x)
{
const int y = x + 1;
foo(y);
return y > x;
}
首先,发言者说,由于foo()函数通过const引用获取“ y”,而“ y”实际上是const int,因此在运行时更改foo()中的值是未定义的行为。似乎在说,由于这是非法的编译器,因此应实际假定对foo()的调用中的“ y”未更改,并且bar()函数应仅返回true而不进行比较。
据我所知,允许编译器仅返回true, 因为foo()更改'y'确实是非法的。
然后说“但不是”,似乎暗示这是编译器的一个缺点,错过了优化。他对此是否正确?
此外,关于“ y”将始终大于“ x”的假设,因此该函数应仅返回true而不是对其进行比较,因此不存在可以传递给该函数的值,即max该类型可以保留的值,其中“ y = x + 1”将导致溢出,这意味着y> x不再为真?我相信签名和未签名都是如此。
因此,在此示例中,有符号整数,“ y”等于“ x”加 1,因此如果“ y”不变,则它现在总是大于“ x”。的 编译器可以对带符号的对象而不是无符号的对象进行这种假设。
他还说:
如果将其更改为按值传递,则它将起作用。
好像要说比较指令不见了,函数只是返回true,但是在给定整数溢出点的情况下,编译器如何做出这种假设?
Here是视频中的相关点。
答案 0 :(得分:3)
签名的int
溢出是不确定的,因此允许编译器忽略x + 1
可能减少 x
的可能性。
编译器在设计优化策略方面越来越好;您可以期望您的函数将被优化为将来调用foo,然后再调用return true;
。