为了提高编译和运行速度,或者为了减少代码段大小,我们常常需要使用编译优化。
默认是-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等字段需要放在函数外部,不能放在函数内部使用。