use*_*683 6 c++ strict-aliasing
在将char数组转换为其他类型时,我对严格的别名规则感到困惑.我知道允许将任何对象转换为char数组,但我不确定反过来会发生什么.
看看这个:
#include <type_traits>
using namespace std;
struct{
alignas (int) char buf[sizeof(int)]; //correct?
} buf1;
alignas(int) char buf2[sizeof(int)]; //incorrect?
struct{
float f; //obviously incorrect
} buf3;
typename std::aligned_storage<sizeof(int), alignof(int)>::type buf4; //obviously correct
int main()
{
reinterpret_cast<int&>(buf1) = 1;
*reinterpret_cast<int*>(buf2) = 1;
reinterpret_cast<int&>(buf3) = 1;
reinterpret_cast<int&>(buf4) = 1;
}
Run Code Online (Sandbox Code Playgroud)
使用g ++ - 5.3.0进行编译只会在main的第二行和第三行产生警告:
$ g++ -fsyntax-only -O3 -std=c++14 -Wall main.cpp
main.cpp: In function ‘int main()’:
main.cpp:25:30: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
*reinterpret_cast<int*>(buf2) = 1;
^
main.cpp:26:29: warning: dereferencing type-punned pointer will break strict-aliasing rules [-Wstrict-aliasing]
reinterpret_cast<int&>(buf3) = 1;
^
Run Code Online (Sandbox Code Playgroud)
gcc是否正确,第1行和第4行是正确的,而第2行和第3行则不正确?我相当确定第4行是正确的(这就是为什么aligned_storage),但这里的规则是什么?
首先,没有警告并不能保证正确性!gcc 在发现有问题的代码方面变得越来越好,但它仍然不是一个静态分析工具(而且这些工具也不完美!)
其次,是的,不允许您通过指向其他类型的指针访问 char 数组。