我在16位目标平台上使用avr-gcc
我想做这样的事情:
#define F_CPU 16000000
#define MIN_UPDATES_PER_REV 100
#define MAX_RPM 10000
#define UPDATE_PERIOD_cy ( F_CPU*60 / (MIN_UPDATES_PER_REV*MAX_RPM) )不出所料,我得到了一个溢出错误,因为MIN_UPDATES_PER_REV*MAX_RPM的计算结果为0xf4240:
bldc.h:9:40: warning: integer overflow in expression [-Woverflow]
#define UPDATE_PERIOD_cy ( F_CPU*60 / (MIN_UPDATES_PER_REV*MAX_RPM) )
^尽管我失去了-Woverflow的好处,但如果我将常量强制转换为32位,并在折叠后转换回uint16_t,事情就会解决:
#define UPDATE_PERIOD_cy (uint16_t)( (uint32_t)F_CPU*60 / ((uint32_t)MIN_UPDATES_PER_REV*MAX_RPM) ))是否可以强制gcc在常量折叠过程中处理大的中间值?
我可以强制预处理器为我做常量折叠吗?
有没有我应该知道的最佳实践?
发布于 2016-09-26 07:14:12
您可以通过向常量添加后缀来指定常量的大小,如100UL或100LL。
另一种解决直接问题的方法是重新排序表达式:
#define UPDATE_PERIOD_cy ( F_CPU*60 / MIN_UPDATES_PER_REV / MAX_RPM) )这将产生相同的结果,但避免了溢出的大型中间件。
发布于 2016-09-25 16:10:59
在常量折叠过程中,是否可以强制gcc处理大的中间值?
不你不能这么做。一般的C语言规则总是被应用。这意味着MIN_UPDATES_PER_REV将被评估为uint16,MAX_RPM将被评估为uint8。乘法的结果不适合uint16and,你得到的是-Woverflow。
我可以强制预处理器为我做常量折叠吗?
预处理器只做宏代换,而GCC做常量折叠。如果问题是关于迫使GCC做常量折叠,不,你不能,但即使没有优化标志,GCC也会做常量折叠。
有没有我应该知道的最佳实践?
这是一个主观的问题。(我认为你已经使用了最好的方法来处理角色选择。因为它是在编译时优化的,所以不会产生执行开销)。
https://stackoverflow.com/questions/39681844
复制相似问题