为什么C编译器会丢弃我的& 0xFF掩码?

时间:2012-02-16 22:04:31

标签: c++ c

我遇到一个问题,其中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(我已经使用强制转换修复了问题,但我仍然不明白为什么它首先放弃了它?)

3 个答案:

答案 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))