爲了提高編譯和運行速度,或者爲了減少代碼段大小,我們常常需要使用編譯優化。
默認是-O0, 我們可以修改爲-O1, -O2,-Os,-O3等。
但是編譯優化有時候並不一定優化到最佳的效果,或者優化的結果需要某些支持才能正確執行。
我曾經碰到過一個現象:
在函數func1()內部定義一個數組:
void func1()
{
uint8_t slot_table[2][8] = {{0,4,1,5,2,6,3,7},{8,12,9,13,10,14,11,15}};
......
uint8_t slot_addr = slot_table[channel][index];
......
}
slot table沒有使用const修飾,就是希望它使用棧空間。
但是編譯優化的結果是,把數組的值放在了data段,然後在使用slot_table之前調用memcpy函數進行數組的拷貝。這樣不僅增加了代碼段的大小(因爲增加了memcpy函數的定義),而且在我們的系統中也不能得到正確的值(data段沒有使用)。
因此,針對func1函數,取消編譯優化:
#pragma GCC push_options
#pragma GCC optimize("O0")
void func1()
{
uint8_t slot_table[2][8] = {{0,4,1,5,2,6,3,7},{8,12,9,13,10,14,11,15}};
......
uint8_t slot_addr = slot_table[channel][index];
......
}
#pragma GCC pop_options
注意,pragma GCC push_options等字段需要放在函數外部,不能放在函數內部使用。