#include <limits.h>
__attribute__ ((noclone, noinline))
int less (int x, int y) {
return x > y;
}
__attribute__ ((noclone, noinline))
int neg (int x) {
return -x;
}
int main(void) {
int x = 1, y = INT_MIN;
return less(x, y) == less(neg(y), neg(x));
}
4条答案
按热度按时间bq3bfh9z1#
y
没有任何值的表达式是假的。如果我们编译这个:字符串
gcc和clang在启用优化后都会生成以下代码:
型
任何其他认为是聪明的答案最有可能使用溢出,实际上是未定义的行为或重复一些C的基本原理。
实际上,对于
x
或y
,没有表达式为false的值:型
给出相同的:
型
似乎有些人忽略了编译器将表达式转换为
return 1
这一事实的含义和意义。这证明了编译器已经明确证明了不存在表达式为false的有效输入。否则它不会被允许进行这种优化。iecba09b2#
当x是有符号整数且x=1时,求一个y值使得(x < y)==(-x > -y)为假。
时
unsigned y = 0
。字符串
输出
型
哎呀,直到后来才看到“查找**
int y
**(十六进制)的值”。离开张贴为维基,因为它回答了标题问题,但得到不允许的细节。
qlzsbp2j3#
答案是
INT_MIN == -INT_MIN
,我想你已经知道它是如何工作的了。但是如果你想做一个实验,觉得编译器优化不好,你可以使用
noclone
属性来防止编译器做常量扩展,noinline
属性让less()
成为main()
的黑盒。字符串
q43xntqr4#
如果
int
定义为32位二进制补码值,则值0x80000000
将无法进行比较。原因是二进制补码值的负端比正端多一个值。任何正值都可以转换为负值,但不是所有负值都可以转换为正值。因此,对于上述值,
y
和-y
实际上是相同的值,第一次比较(x < y)
将产生“false”,而(-x > -y)
将产生“true”,使整个表达式为“false”。但如果编译器优化了函数,就不会发生这种情况,就像@bolov的回答一样。