C-确实优化改变了演员的行为

  • 本文关键字:优化 改变 c gcc gcc4
  • 更新时间 :
  • 英文 :


我正在使用一个小型UART设备,并且经常需要切换其操作的波特率。
本质上,整个设置归结为

#define FOSC 2000000
#define BAUD 9600
uint8_t rate = (uint8_t) ((FOSC / (16.0 * BAUD)) - 1 + 0.5);

(其中 0.5用于圆形结果。)

我目前正在使用GCC 4.8.1,-O1
编译器是否优化了整个演员阵容,还是我留下的是铸件,然后是常数?这与不同的-O#值(除-O0)会有所不同吗?那-Os呢(我可能最终必须使用它)?

如果很重要,我正在为Atmel AT90USB647开发(或DataSheet [PDF] )。

极有可能的,任何理智的编译器都会在启用优化的编译时将整个表达式(包括铸件)转换为常数。

但是,可以肯定的是,您需要查看编译器的组件输出。

但是尤其是GCC 4.8.1?

代码

#include <stdint.h>
#include <stdio.h>
#define FOSC 2000000
#define BAUD 9600
int main() {
    uint8_t rate = (uint8_t) (FOSC / (16.0 * BAUD)) - 1 + 0.5;
    printf("%u", rate);
}

gcc -O1 red.c

生成的组件的一部分
main:
.LFB11:
    .cfi_startproc
    subq    $8, %rsp
    .cfi_def_cfa_offset 16
    movl    $12, %esi
    movl    $.LC0, %edi
    movl    $0, %eax
    call    printf

我们可以清楚地看到,GCC预先计算了rate12值。

atmel avr shreips newlib c库,它是一个简单的ANSI C库,数学库和董事会支持软件包的集合。您可以参考ANSI C规格以找出答案。特别是转换部分。

我将确保将速率写入挥发性变量或指针。也许可以计算速率值,但是当它写入外围目的地时,它缺少挥发性标签,而优化器不执行写入操作。

最新更新