繁体   English   中英

printf和gcc -O选项更改返回值

[英]printf and gcc -O option change return value

我试图了解gcc -O选项和printf如何更改返回值。

在下面的代码中, isTmax是我的函数,如果输入是最大的int值,则返回1。

int isTmax(int x);
int main(void)
{
    printf("%d\n", isTmax(0x7fffffff));
}

int isTmax(int x)
{
    int temp = x + x + 2;
    int result = !temp & (!!(~x));
    return result;
}

当我在没有gcc选项的情况下编译它时,它工作得很好。

但是使用-O选项,所有整数值都为0。

所以我添加了printf来检查值,然后使用-O选项对其进行编译。

int isTmax(int x)
{
    int temp = x + x + 2;
    int result = !temp & (!!(~x));
    printf("x : %x, temp : %x, !temp : %x\n", x, temp , !temp); 
    return result;
}

突然,它又开始工作了。

我想知道为什么返回值会变化。

正如评论中指出的那样,这是由于行为不确定。

现代编译器可以(ab)使用未定义的行为来简化,缩短和加速编译的代码,而不会违反任何规则。 我建议您阅读那篇有关UB危害的出色文章

很难知道到底发生了什么,因为优化器变得异常复杂,但这是编译器可能会对您的函数进行的处理。

(1) int isTmax(int x)
(2) {
(3)     int temp = x + x + 2;
(4)     int result = !temp & (!!(~x));
(5)     return result;
(6) }

在第3行中,您将两个有符号整数加在一起。 如果您的程序仅使用0x7fffffff调用此函数一次,则编译器已经知道该代码仅产生整数溢出。 该代码有一个错误之处; 由于您将2加到一个溢出的操作中,因此编译器可以假定该值将为正数,并且为了接下来的处理,该值大于2。

在第4行, !temp转换为布尔常量false因为temp被假定为正值。 接下来, and 由于左侧的值为false(或0), result总是以0结尾。如果结果始终为零,则优化器可能会删除所有变量和运算。

因此从本质上讲,经过优化后,您的函数如下所示:

int isTmax(int x)
{
    return 0;
}

通过在printf内部添加一个printf ,您将迫使优化器去优化,因此最终您将得到不优化程序时得到的相同代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM