工作中的代码库包含一些看起来大致如下的代码:
#define DATA_LENGTH 64
u_int32 SmartKey::SerialNumber()
{
unsigned char data[DATA_LENGTH];
// ... initialized data buffer
return *(u_int32*)data;
}
Run Code Online (Sandbox Code Playgroud)
此代码可以正常工作,但GCC会发出以下警告:
warning: dereferencing pointer ‘serialNumber’ does break strict-aliasing rules
Run Code Online (Sandbox Code Playgroud)
有人可以解释这个警告吗?这个代码有潜在危险吗?怎么改进?
更新
感谢James McNellis的回答,我提出了以下实用功能:
template<class T, class Data>
T BinaryCast(const Data & inData)
{
T ret;
std::copy(&inData[0], &inData[0] + sizeof(ret), reinterpret_cast<char*>(&ret));
return ret;
}
u_int32 SmartKey::SerialNumber()
{
unsigned char data[DATA_LENGTH];
// ... initialized data buffer
return BinaryCast<u_int32>(data);
}
Run Code Online (Sandbox Code Playgroud)
随意提出改进建议!
Jam*_*lis 11
警告是因为您违反了严格别名规则.
正确执行此操作的一种方法是将data缓冲区中的字节复制到u_int32对象中并返回该对象:
unsigned char data[DATA_LENGTH];
// ... initialized data buffer
u_int32 i;
assert(sizeof (i) <= DATA_LENGTH);
std::copy(&data[0], &data[0] + sizeof (i), reinterpret_cast<char*>(&i));
return i;
Run Code Online (Sandbox Code Playgroud)
此解决方案有效,因为在C++中,它允许以数组形式访问任何类型的对象char.
(std::copy()在<algorithm>)