2014-03-30 43 views
1

家伙,我有从8位 1抽取32位可变码接下来的两件)首先是:操作可能未定义的宏

#include <stdio.h> 
#include <string.h> 

int main() 
{ 
    unsigned char buffer[] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee}; 
    unsigned char *buff = buffer; 
    unsigned int result; 
    result = *buff++; 
    result += *buff++ <<8; 
    result += *buff++ << 16; 
    result += *buff++ <<24; 

    printf("result = 0x%x, *buffer = 0x%x.", result, *buff); 

    return 0; 
} 

没有任何警告,但它看起来有点跛....

2)在第二,我们有宏观的,而不是那些丑陋的4条线路:

#include <stdio.h> 
#include <string.h> 

#define to32(buffer) ((unsigned int)*buffer++ | *buffer++ << 8 | *buffer++ << 16 | *buffer++ << 24) 

int main() 
{ 
    unsigned char buffer[] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee}; 
    unsigned char *buff = buffer; 
    unsigned int result = to32(buff); 

    printf("result = 0x%x, *buffer = 0x%x.", result, *buff); 

    return 0; 
} 

而且它的叶子下一个警告:

main.cpp: In function 'int main()': 

main.cpp:4:99: warning: operation on 'buff' may be undefined [-Wsequence-point] 

#define to32(buffer) ((unsigned int)*buffer++ | *buffer++ << 8 | *buffer++ << 16 | *buffer++ << 24) 

我有点困惑GCC发现什么是未定义的行为。 是不是所有的移动都在一行中,我总结它?

+0

我将调查此问题。基本上我很困惑,因为代码的两个部分几乎是相同的,但由于某种原因当你把它写成这个宏时,它会被编译为警告 – Douman

回答

2

编辑 一种解决方案是:

static inline unsigned to32(const unsigned char *buffer) 
{ 
    return buffer[0] | buffer[1] << 8 | buffer[1] << 16 | buffer[3] << 24; 
} 

如果你真的不喜欢的功能,你可以做一个宏一样...

它是关于那些sequence-points编译警告你。

的顺序没有定义如下:

to32(buffer) ((unsigned int)*buffer++ | *buffer++ << 8 | *buffer++ << 16 | *buffer++ << 24) 
    // will be 
    buffer = *buffer++; 
    buffer |= *buffer++ << 8; 
     .... 

    // or 
    buffer = *buffer++ << 8; 
    buffer |= *buffer++; 
    ... 

||&&情况下在操作序列点,操作有一个顺序,从左到右。但不在|& 订单未定义,编译器可以按任意顺序执行。

+0

同样会出现'+',我猜这有点难过:(我希望有一个宏,实际上我觉得有点奇怪,顺序不是对于那些运算符是严格的 – Douman

+2

@Douman您可以编写一个不使用'++'运算符的等价表达式,对于这个运算符,序列点不会影响 – augurar

+0

是的,您可以索引缓冲区' –

0

经过来自Buella Gabor和Auguar的一些建议,我觉得我可以这样做。 它似乎是正确的

#define to32(buffer) ((unsigned int)*buffer | *(buffer+1) << 8 | *(buffer+2) << 16 | *(buffer+3) << 24) 

虽然它并不适合我的需要:(