【问题标题】:What are the strict aliasing rules when casting *from* a char array?转换 *from* char 数组时有哪些严格的别名规则?
【发布时间】:2016-05-18 14:32:51
【问题描述】:

在将 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;
}

使用 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;
                             ^

gcc 是否正确,因为第 1 和第 4 行是正确的,而第 2 和第 3 行不正确?我很确定第 4 行是正确的(这就是 aligned_storage 的用途),但这里的规则是什么?

【问题讨论】:

  • 不允许反之。
  • 所有这些都是 UB(不确定您所说的“显然正确”是什么意思)

标签: c++ strict-aliasing


【解决方案1】:

首先,没有警告并不能保证正确性! gcc 在发现有问题的代码方面越来越好,但它仍然不是一个静态分析工具(而且那些也不完美!)

其次,是的,不允许您通过指向其他类型的指针访问 char 数组。

【讨论】:

  • 带一些术语和引用会很好。
猜你喜欢
  • 2014-07-13
  • 2015-03-30
  • 2017-05-08
  • 1970-01-01
  • 2015-10-15
  • 2017-02-25
  • 2015-01-17
  • 2016-09-12
相关资源
最近更新 更多