首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在16位目标架构上的常量折叠期间溢出

在16位目标架构上的常量折叠期间溢出
EN

Stack Overflow用户
提问于 2016-09-25 07:16:33
回答 2查看 105关注 0票数 1

我在16位目标平台上使用avr-gcc

我想做这样的事情:

代码语言:javascript
复制
#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:

代码语言:javascript
复制
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,事情就会解决:

代码语言:javascript
复制
#define UPDATE_PERIOD_cy (uint16_t)( (uint32_t)F_CPU*60 / ((uint32_t)MIN_UPDATES_PER_REV*MAX_RPM) ))

是否可以强制gcc在常量折叠过程中处理大的中间值?

我可以强制预处理器为我做常量折叠吗?

有没有我应该知道的最佳实践?

EN

回答 2

Stack Overflow用户

发布于 2016-09-26 07:14:12

您可以通过向常量添加后缀来指定常量的大小,如100UL100LL

另一种解决直接问题的方法是重新排序表达式:

代码语言:javascript
复制
#define UPDATE_PERIOD_cy ( F_CPU*60 / MIN_UPDATES_PER_REV / MAX_RPM) )

这将产生相同的结果,但避免了溢出的大型中间件。

票数 2
EN

Stack Overflow用户

发布于 2016-09-25 16:10:59

在常量折叠过程中,是否可以强制gcc处理大的中间值?

不你不能这么做。一般的C语言规则总是被应用。这意味着MIN_UPDATES_PER_REV将被评估为uint16,MAX_RPM将被评估为uint8。乘法的结果不适合uint16and,你得到的是-Woverflow。

我可以强制预处理器为我做常量折叠吗?

预处理器只做宏代换,而GCC做常量折叠。如果问题是关于迫使GCC做常量折叠,不,你不能,但即使没有优化标志,GCC也会做常量折叠。

有没有我应该知道的最佳实践?

这是一个主观的问题。(我认为你已经使用了最好的方法来处理角色选择。因为它是在编译时优化的,所以不会产生执行开销)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39681844

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档