Я читал о строгих правилах псевдонимов за последнюю неделю или около того и наткнулся на эту статью: Понимание C/С++ Strict Aliasing.
В статье рассмотрены несколько способов обмена двумя половинами 32-разрядного целого числа, что дает как хорошие примеры, так и те, которые нарушают правило строгого сглаживания. Однако мне трудно понять один из примеров.
Этот код описан как сломанный.
uint32_t
swaphalves(uint32_t a)
{
a = (a >> 16) | (a << 16);
return a;
}
Приведенная причина:
Эта версия выглядит разумно, но вы не знаете, есть ли правая и левая стороны | каждый получит исходную версию
a
или если один из них получит результат другой. Здесь нет точки последовательности, поэтому мы ничего не знаем о порядке операции, и вы можете получать разные результаты от одного и того же компилятора, используя разные уровни оптимизации.
Я не согласен. Этот код выглядит хорошо для меня. В строке a = (a >> 16 | (a << 16);
есть только одна запись в a
, и я ожидаю, что оба чтения a
пройдут до этой записи. Кроме того, нет указателей или ссылок и нет несовместимых типов.
Мне не хватает строгого нарушения псевдонимов в этом коде или неверна статья?