首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带内建函数的奇异GCC6优化

带内建函数的奇异GCC6优化
EN

Stack Overflow用户
提问于 2018-06-15 15:34:11
回答 4查看 112关注 0票数 1

使用GCC6和下面的代码片段,这个测试

代码语言:javascript
复制
if (i > 31 || i < 0) {

false,并且执行此printf。

代码语言:javascript
复制
printf("i > 31 || i < 0 is FALSE, where i=%d", i);

并产生这个非常奇怪的输出(GCC6):

i > 31 x\i<0是FALSE,其中i=32 /*与GCC6 !!*/的结果很奇怪。

然而,对于GCC4,我得到了:

i > 31 \x\i<0是true,其中i=32 /*的结果与GCC4 */一致。

看起来很好。

,这怎么可能??

代码片段(损坏的遗留代码!):

代码语言:javascript
复制
static int check_params(... input parameters ...) {
    /* Note that value can be 0 (zero) */
    uint32_t value = ....
    int i;

    i = __builtin_ctz(value);
    if (i > 31 || i < 0) {
        printf("i > 31 || i < 0 is true, where i=%d", i);
        /* No 1 found  */
        return 0;
    } else {
        printf("i > 31 || i < 0 is FALSE, where i=%d", i);
    }
    return i;
}

根据GCC内建函数文献,必须避免调用__builtin_ctz(0):

内置函数: int __builtin_ctz (无符号int x)返回x中尾随0位数,从最不重要的位位置开始。如果x为0,则结果为未定义的

因此,显然,编码错误的解决方案是在调用__builtin_ctz( value )之前简单地检查该值。这一点很清楚,也是可以理解的。

我可以停下来,转到其他主题.,但是,我还是不明白我怎么可能(用坏了的代码)得到以下输出:

i > 31 x\i<0是FALSE,其中i=32 /*与GCC6 !!*/的结果很奇怪。

奇怪的GCC6优化什么的?

以防万一:

代码语言:javascript
复制
Cross-compiler: arm-linux-gcc
Architecture: -march=armv7-a

有什么想法吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-06-15 15:42:36

除非行为不明确,__builtin_ctz总是会返回一个介于0到31之间的数字,GCC知道这一点。因此,check i > 31 || i < 0将始终为false (同样禁止未定义的行为),并且可以进行优化。

如果您查看生成的程序集,您将看到这个条件根本没有出现在代码中(当时的大小写也没有)。

票数 6
EN

Stack Overflow用户

发布于 2018-06-15 15:42:59

未定义的行为并不意味着“值将是任意的”。这意味着编译器可以执行从字面上说,它想要什么。在这种情况下,编译器似乎能够静态地验证,只要value不是0,i总是包含在0到31之间。因此,它甚至不费事地为时间子句生成代码。

你只是幸运的恶魔没从你鼻子里出来。

请参见:未定义的行为会导致时间旅行。过早的低潮为什么未定义的行为可以调用从未调用的函数?UB的许多其他讨论

票数 4
EN

Stack Overflow用户

发布于 2018-06-15 15:45:32

编译器假定未定义的行为不会发生。它可以作出这一假设,因为如果违反限制条件,行为不明确,就有可能产生任何结果,包括不正确的假设所产生的结果。

如果没有未定义的行为,那么i不能是负的或大于31。在此基础上,可以在编译时优化if语句中的条件。

printf实际打印的值无法预测,因此它实际上调用了printf,不管i是什么。在这种情况下,它碰巧是32,但它可能是任何东西。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50878726

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档