将 char 数组转换为另一种类型是否违反严格的别名规则?

Does casting a char array to another type violate strict-aliasing rules?

考虑这两个函数:

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

警告是否合法?

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

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

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

完全合法吗。您可以将 char*(或 void*)用作 "universal pointer" - 前提是您在访问前转换回正确的类型。 GCC 显然在避免对 f3 发出警告,但以不对 f2.

发出警告为代价

Clang 未能就 f1f2 发出警告 - 但并非必须如此。