这是一个关于严格别名问题的疑问,即编译器是否会因此导致任何优化顺序问题。
比如说我有三个公共的
我假设这段代码总是会输出"13"。但是对于下面的代码呢:
我认为这是合法的,因为根据http://en.cppreference.com/w/cpp/language/reinterpret_cast#Type_aliasing
T2是聚合类型或联合类型,其中包含一个前述类型作为元素或非静态成员(包括递归地包含子聚合的元素和包含它的联合的非静态数据成员):这使得从结构体的第一个成员和联合的元素向包含它的结构体/联合转换是安全的。
我的理解正确吗?
显然,这将取决于XMFLOAT3的声明,具体实现可能会有所不同。
比如说我有三个公共的
float
在struct XMFLOAT3
中(类似于这个)。我想强制转换成一个float*
。这会导致优化问题吗?XMFLOAT3 foo = {1.0f, 2.0f, 3.0f};
auto bar = &foo.x;
bar[2] += 5.0f;
foo.z += 5.0f;
cout << foo.z;
我假设这段代码总是会输出"13"。但是对于下面的代码呢:
XMFLOAT3 foo = {1.0f, 2.0f, 3.0f};
auto bar = reinterpret_cast<float*>(&foo);
bar[2] += 5.0f;
foo.z += 5.0f;
cout << foo.z;
我认为这是合法的,因为根据http://en.cppreference.com/w/cpp/language/reinterpret_cast#Type_aliasing
T2是聚合类型或联合类型,其中包含一个前述类型作为元素或非静态成员(包括递归地包含子聚合的元素和包含它的联合的非静态数据成员):这使得从结构体的第一个成员和联合的元素向包含它的结构体/联合转换是安全的。
我的理解正确吗?
显然,这将取决于XMFLOAT3的声明,具体实现可能会有所不同。
(&foo.x)[2]
看起来像是一个明显的越界数组访问,编译器很容易就能发现。 - MSaltersfloat[3]
的三个元素一样对齐,所以这确实是一个棘手的问题。(&foo.x)[2]
等同于*(&foo.x + 2)
,3.9.2/3规定只要该地址确实有一个float
,那么它就是良好形式,这又回到了填充和对齐的问题。 - Jonathan Wakelystatic_assert
可以用来防止一些不靠谱的编译器。(无意冒犯啊,小动物们) - Jonathan Mee