我正在使用一个小型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预先计算了rate
的12
值。
atmel avr shreips newlib c库,它是一个简单的ANSI C库,数学库和董事会支持软件包的集合。您可以参考ANSI C规格以找出答案。特别是转换部分。
我将确保将速率写入挥发性变量或指针。也许可以计算速率值,但是当它写入外围目的地时,它缺少挥发性标签,而优化器不执行写入操作。