将 char 数组转换为另一种类型是否违反严格的别名规则?
Does casting a char array to another type violate strict-aliasing rules?
考虑这两个函数:
int f1()
{
alignas(int) char buf[sizeof(int)] = {};
return *reinterpret_cast<int*>(buf);
}
int f2()
{
alignas(int) char buf[sizeof(int)] = {};
char* ptr = buf;
return *reinterpret_cast<int*>(ptr);
}
GCC 警告第一个违反严格的别名规则。但是第二个还可以。
Clang 毫无怨言地接受了两者。
警告是否合法?
警告是合法的。 f2
不正常(这是未定义的行为),它只是不会引发警告。
我怀疑 f2
没有引起警告的原因是:
int f3()
{
int i = 0;
char *ptr = reinterpret_cast<char*>(&i);
return *reinterpret_cast<int*>(ptr);
}
完全合法吗。您可以将 char*
(或 void*
)用作 "universal pointer" - 前提是您在访问前转换回正确的类型。 GCC 显然在避免对 f3
发出警告,但以不对 f2
.
发出警告为代价
Clang 未能就 f1
或 f2
发出警告 - 但并非必须如此。
考虑这两个函数:
int f1()
{
alignas(int) char buf[sizeof(int)] = {};
return *reinterpret_cast<int*>(buf);
}
int f2()
{
alignas(int) char buf[sizeof(int)] = {};
char* ptr = buf;
return *reinterpret_cast<int*>(ptr);
}
GCC 警告第一个违反严格的别名规则。但是第二个还可以。
Clang 毫无怨言地接受了两者。
警告是否合法?
警告是合法的。 f2
不正常(这是未定义的行为),它只是不会引发警告。
我怀疑 f2
没有引起警告的原因是:
int f3()
{
int i = 0;
char *ptr = reinterpret_cast<char*>(&i);
return *reinterpret_cast<int*>(ptr);
}
完全合法吗。您可以将 char*
(或 void*
)用作 "universal pointer" - 前提是您在访问前转换回正确的类型。 GCC 显然在避免对 f3
发出警告,但以不对 f2
.
Clang 未能就 f1
或 f2
发出警告 - 但并非必须如此。