将字符数组强制转换为另一种类型是否违反了严格别名规则?

14

考虑这两个函数:

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或者char数组,而glvalue的类型是int; https://timsong-cpp.github.io/cppwp/basic.lval#8中没有涵盖这种情况。 - T.C.
@T.C. 你的意思是说,按照标准,无法将char类型的某个区域别名为其他类型T吗?因为这就是可选和变体的工作方式。如果这是真的,我不禁觉得这个想法对这些实际需求来说是一个风险。我认为char是包括在别名异常中的,目的就是为了这个。 - v.oddou
1个回答

10

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

我怀疑 f2 不引发警告的原因是:

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

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

Clang未能警告f1f2,但这并非必须。


5
需要标准引号。 - Euri Pinhollow

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接