Выбрасывает ли массив char другому типу правил строгого сглаживания?

Рассмотрим эти две функции:

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 предупреждает, что первое нарушение правил строгого сглаживания. Но второй - ОК.

Кланг принимает оба без жалобы.

Является ли предупреждение законным?

Ответ 1

Предупреждение является законным. f2 не в порядке (это поведение undefined), это просто не вызывает предупреждения.

Я подозреваю, что причина, по которой 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 - но это не требуется.