我遇到一个问题,其中2个不同的编译器(GCC和IAR)从不同大小的变量中删除了我的掩码。
我有以下代码:
uint8_t Value2;
uint16_t WriteOffset;
bool Fail;
void test(void)
{
uint8_t buff[100];
uint16_t r;
for(r=0;r<Value2+1;r++)
{
if(buff[r]!=(WriteOffset+r)&0xFF)
{
Fail=true;
}
}
}
当buff[r]
== 0和WriteOffset+r
== 0x100时,if失败(进入{}块)。
GCC输出以下程序集:
movzwl -0xc(%ebp),%eax ; Load 'r'->EAX
mov -0x70(%ebp,%eax,1),%al ; Load 'buff[r]'->AL
movzbl %al,%edx ; Move AL to (unsigned int)EDX
mov 0x4b19e0,%ax ; Load 'WriteOffset'->AX
movzwl %ax,%ecx ; Move AX to (unsigned int)ECX
movzwl -0xc(%ebp),%eax ; Load 'r'->EAX
lea (%ecx,%eax,1),%eax ; 'WriteOffset' + 'r'->EAX
cmp %eax,%edx ; (unsigned int)'WriteOffset+r' == (unsigned int)'buff[r]'
je 0x445e28 <Test+1254> ; If == skip {} block
我的问题是为什么编译器会从if中删除&0xFF
(我已经使用强制转换修复了问题,但我仍然不明白为什么它首先放弃了它?)
答案 0 :(得分:14)
不是,operator precedence在这里咬你
您想要if( buff[r] != ((WriteOffset+r)&0xFF) )
您目前拥有的内容与if( (buff[r]!=(WriteOffset+r)) & 0xFF )
优先级混乱导致您使用0xFF屏蔽只能为0或1(比较表达式的结果)的值,因此优化器可以合理地删除它。
答案 1 :(得分:3)
!=
的优先级高于&
。我想你需要一套额外的括号。
http://en.wikipedia.org/wiki/Operators_in_C_and_C%2B%2B有一个C / C ++运算符优先级表,看一下。
答案 2 :(得分:3)
运营商!=
的优先级高于&
。所以你应该这样写:
if(buff[r]!=((WriteOffset+r)&0xFF))