我在一些传统的源代码中有一句话:
#define MAXMSG 1024
...
char m_recvBuf[MAXMSG];
unsigned int msgLength = ntohl(*((unsigned int *)m_recvBuf));
这会产生以下警告:
x.cpp: In member function ‘bool xx::cccc(std::string&)’:
x.cpp:308: warning: dereferencing type-punned pointer will break strict-aliasing rules
我怎样摆脱这个警告?
我的编译行:
g++ -c -g -O2 -Wall -DDEBUG_ON -D_VERSION_=\"1.0.0\" `xml2-config --cflags` -I../src -I./common -I. -I../../test/ -o common/xx.o common/xx.cpp
$ g++ --version
g++ (GCC) 4.4.6 20110731 (Red Hat 4.4.6-3)
答案 0 :(得分:3)
您的代码存在的问题是违反了strict aliasing rules,因此可能不安全。
您可以使用-Wno-strict-aliasing
隐藏警告(这不会解决您的问题),修改数据结构或完全避免问题,方法是指定二进制副本的位置和长度,如Matt建议的那样(可能最好的选择):
unsigned int msgLength;
memcpy(&msgLength, m_recvBuf, sizeof(msgLength));
msgLength = ntohl(msgLength);
注意:我在-O3中没有得到clang 3.4和gcc 4.8.2的错误,这意味着编译器可能已经优化了警告。无论如何,这并不能保证您的代码是安全的。
答案 1 :(得分:2)
正如之前的响应者所说,你可以改变编译标志,使警告消失。如果你开始进行一些轻微的重构,你可以用这样的联盟更清楚地解决这个问题:
#define MAXMSG 1024
union {
char buf[MAXMSG];
unsigned int length;
} recvbuf;
// [ read your message stream to recvbuf.buf ]
unsigned int msgLength = ntohl(recvbuf.length);