优化是否会改变演员表的行为?

时间:2015-05-10 19:02:31

标签: 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])。

3 个答案:

答案 0 :(得分:3)

非常可能任何理智的编译器都会在启用优化的情况下编译时将整个表达式(包括强制转换)转换为常量。

但是,当然,您需要查看编译器的汇编输出。

但是特别是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已为12预先计算了rate的值。

答案 1 :(得分:0)

Atmel AVR发布了newlib C库,它是一个简单的ANSI C库,数学库和板级支持包的集合。您可以参考ANSI C规范来查找。特别是转换部分。

答案 2 :(得分:0)

我会确保将速率写入易失性变量或指针。也许速率值计算正常,但是当它写入外设目的地时,它缺少volatile标记,优化器不执行写操作。