溢出

2016-09-24 176 views
1

我使用一個16位的目標平臺上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)) 
                 ^

事情工作了,如果我強迫常數爲32位和轉換回折後uint16_t,雖然我失去了好處水流量:

#define UPDATE_PERIOD_cy (uint16_t)((uint32_t)F_CPU*60/((uint32_t)MIN_UPDATES_PER_REV*MAX_RPM))) 

我可以強制gcc在常量摺疊期間處理大的中間值嗎?

我可以強制預處理器爲我做不斷摺疊嗎?

我應該知道哪些最佳實踐?

+0

你知道誰提供這個編譯器嗎?你有沒有試圖要求他們修復? – ddbug

+0

編譯器運行正常。我希望找到一種方式,使其行爲方式不正確,但稍微方便一些。 – fkoran

回答

0

我可以強制gcc在常量 摺疊期間處理大的中間值嗎?

不,你不能這樣做。一般C規則總是被應用。含義MIN_UPDATES_PER_REV將被評估爲uint16和MAX_RPM到uint8。乘法的結果不適合uint16並且您將獲得-Woverflow。

我可以強制預處理器爲我做持續摺疊嗎?

預處理器只做宏替換,GCC做常量摺疊。如果問題是強迫GCC做不斷的摺疊,否則你不能不做,即使沒有優化標誌,GCC也會做不斷的摺疊。

我應該知道哪些最佳實踐?

這是一個主觀問題。 (我認爲你已經使用了最好的方式來處理cast,因爲它在編譯時被優化了,所以你沒有執行過度成本)。

2

您可以通過向其添加後綴來指定常量的大小,如100UL100LL

另一種方式來解決你的直接問題是重新排序的表達式:

#define UPDATE_PERIOD_cy (F_CPU*60/MIN_UPDATES_PER_REV/MAX_RPM)) 

這將產生相同的結果,但避免了大的中間體,其溢出。