在这个答案中,有一段关于严格别名规则的引用,针对C++11规范,内容如下:
好的,严格别名规则得到满足。但是还有其他原因导致未定义行为吗?
所以我认为下面的代码不违反严格别名规则:如果程序试图通过除以下类型之一的glvalue来访问对象的存储值,则行为是未定义的:
...
包括上述类型之一在其元素或非静态数据成员中的聚合体或联合体类型(包括,递归地,子聚合体或包含联合体的元素或非静态数据成员),
...
#include <iostream>
#include <cstdint>
#include <climits>
#include <limits>
struct PunnerToUInt32
{
std::uint32_t ui32;
float fl;
};
int main()
{
static_assert(std::numeric_limits<float>::is_iec559 &&
sizeof(float)==4 && CHAR_BIT==8,"Oops");
float x;
std::uint32_t* p_x_as_uint32=&reinterpret_cast<PunnerToUInt32*>(&x)->ui32;
*p_x_as_uint32=5;
std::cout << x << "\n";
}
好的,严格别名规则得到满足。但是还有其他原因导致未定义行为吗?
reinterpret_cast
,并且它不是用于char*
,那么在99.9%的情况下,你正在面对严格别名违规问题(0.1%的情况是保留给指针实际上没有被解引用,而是用于另一种允许的转换的情况)。 - SergeyA