相关疑难解决方法(0)

为什么这个循环产生"警告:迭代3u调用未定义的行为"并输出超过4行?

编译:

#include <iostream>

int main()
{
    for (int i = 0; i < 4; ++i)
        std::cout << i*1000000000 << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

gcc产生以下警告:

warning: iteration 3u invokes undefined behavior [-Waggressive-loop-optimizations]
   std::cout << i*1000000000 << std::endl;
                  ^
Run Code Online (Sandbox Code Playgroud)

我知道有一个有符号的整数溢出.

我不能得到的是为什么i价值被溢出操作打破了?

我已经阅读了为什么x86上的整数溢出与GCC导致无限循环的答案,但我仍然不清楚为什么会发生这种情况 - 我认为"未定义"意味着"任何事情都可能发生",但这种特定行为的根本原因是什么?

在线:http://ideone.com/dMrRKR

编译: gcc (4.8)

c++ gcc undefined-behavior

160
推荐指数
5
解决办法
6万
查看次数

GCC如何优化循环内增加的未使用变量?

我写了这个简单的C程序:

int main() {
    int i;
    int count = 0;
    for(i = 0; i < 2000000000; i++){
        count = count + 1;
    }
}
Run Code Online (Sandbox Code Playgroud)

我想看看gcc编译器如何优化这个循环(显然添加1 2000000000次应该是"一次添加2000000000 ").所以:

GCC test.c的,然后timea.out给出了:

real 0m7.717s  
user 0m7.710s  
sys 0m0.000s  
Run Code Online (Sandbox Code Playgroud)

$ gcc -O2 test.c 然后time ona.out`给出:

real 0m0.003s  
user 0m0.000s  
sys 0m0.000s  
Run Code Online (Sandbox Code Playgroud)

然后我用两个人拆开了gcc -S.第一个似乎很清楚:

    .file "test.c"  
    .text  
.globl main
    .type   main, @function  
main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    movq    %rsp, %rbp
    .cfi_offset 6, …
Run Code Online (Sandbox Code Playgroud)

c gcc disassembly compiler-optimization

64
推荐指数
1
解决办法
7410
查看次数

如何防止GCC优化忙等待循环?

我想为Atmel AVR微控制器编写C代码固件.我将使用GCC编译它.此外,我想启用编译器优化(-Os-O2),因为我认为没有理由不启用它们,并且它们可能比手动编写汇编更快地生成更好的汇编方式.

但我想要一小段没有优化的代码.我想延迟函数的执行一段时间,因此我想写一个do-nothing循环只是为了浪费一些时间.不需要精确,只需等待一段时间.

/* How to NOT optimize this, while optimizing other code? */
unsigned char i, j;
j = 0;
while(--j) {
    i = 0;
    while(--i);
}
Run Code Online (Sandbox Code Playgroud)

由于AVR中的内存访问速度要慢得多,因此我希望i并将j其保存在CPU寄存器中.


更新:我刚刚发现UTIL/delay.hUTIL/delay_basic.hAVR libc库.尽管大多数情况下使用这些功能可能更好,但这个问题仍然有效且有趣.


相关问题:

c optimization gcc avr-gcc

62
推荐指数
4
解决办法
5万
查看次数

编译器是否允许消除无限循环?

可以优化编译器删除无限循环,这不会改变任何数据,如

while(1) 
  /* noop */;
Run Code Online (Sandbox Code Playgroud)

从分析编译器可以推导出的数据流图,这样的循环是"死代码"而没有任何副作用.

是否删除了C90/C99标准禁止的无限循环?

C90或C99标准是否允许编译器删除此类循环?

更新:"Microsoft C版本6.0基本上做了这个优化.",请参阅caf的链接.

label: goto label;
return 0;
Run Code Online (Sandbox Code Playgroud)

将转变为

return 0;
Run Code Online (Sandbox Code Playgroud)

c compiler-construction optimization standards infinite-loop

30
推荐指数
3
解决办法
5512
查看次数