Нарушает ли приведение массива символов к другому типу строгие правила псевдонимов?

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

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 принимает оба без жалоб.

Правомерно ли предупреждение?


person John Zwinck    schedule 23.12.2016    source источник
comment
Да. Объект здесь либо char, либо массив chars, а glvalue имеет тип int; ничего в timsong-cpp.github.io/cppwp/basic.lval#8 покрывает этот случай.   -  person T.C.    schedule 23.12.2016
comment
@Т.С. Вы имеете в виду, что по стандарту невозможно использовать псевдоним области char, как какой-либо другой тип T? потому что так работает необязательно и вариант, не так ли. Я не могу не найти в этой идее, если она верна, риск для этих практических нужд. Я думал, что исключения из псевдонимов включают char для этой цели.   -  person v.oddou    schedule 02.08.2019


Ответы (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, но это и не требуется.

person Martin Bonner supports Monica    schedule 23.12.2016
comment
Нужны стандартные цитаты. - person Euri Pinhollow; 02.12.2017