【问题标题】:Does casting a char array to another type violate strict-aliasing rules?将 char 数组转换为另一种类型是否违反严格的别名规则?
【发布时间】:2017-05-08 23:49:25
【问题描述】:

考虑这两个函数:

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 毫无怨言地接受了两者。

警告合法吗?

【问题讨论】:

  • 是的。这里的“对象”是char 或chars 的数组,glvalue 的类型为int; timsong-cpp.github.io/cppwp/basic.lval#8 中没有任何内容涉及这种情况。
  • @T.C.您的意思是按照标准,将 char 区域别名为其他类型 T 是不可能的?因为这就是可选和变体的工作方式,不是吗。我不禁发现这个想法,如果是真的,对这些实际需求有风险。我认为别名的例外是为此目的包括 char。

标签: c++ language-lawyer compiler-warnings reinterpret-cast strict-aliasing


【解决方案1】:

警告是合法的。 f2 不行(它是未定义的行为),它只是不会引发警告。

我怀疑f2 没有引起警告的原因是:

int f3()
{
    int i = 0;
    char *ptr = reinterpret_cast<char*>(&i);
    return *reinterpret_cast<int*>(ptr);
}

完全合法。您可以使用char*(或void*)作为“通用指针”——前提是您在访问之前转换回正确的类型。 GCC 显然小心翼翼地避免警告 f3,代价是不警告 f2。

Clang 未能就f1 或f2 发出警告——但这不是必需的。

【讨论】:

  • 需要标准引号。
猜你喜欢
  • 1970-01-01
  • 2021-08-19
  • 2010-12-27
  • 2020-02-08
  • 1970-01-01
  • 2020-04-11
  • 1970-01-01
  • 2016-02-24
相关资源
最近更新 更多