伙计我接下来有两段代码从8位提取32位变量 1)首先是:
#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 :(得分: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++;
...
如果||
和&&
在运算符处有一个序列点,并且操作有一个从左到右的顺序。但不是|
和&
订单未定义,编译器可以按任何顺序执行。
答案 1 :(得分:0)
经过Buella Gabor和auguar的一些建议后,我发现我可以这样做。 它似乎是正确的
#define to32(buffer) ((unsigned int)*buffer | *(buffer+1) << 8 | *(buffer+2) << 16 | *(buffer+3) << 24)
虽然它并不能满足我的需求:(