Информация об изменениях

Сообщение Re[2]: Как обойти strict aliasing rule? от 17.06.2016 10:10

Изменено 21.06.2016 9:53 S. Schlongberg

Здравствуйте, Erop, Вы писали:

E>А зачем? В том смысле, что на разных платформах могут быть разные эндианы, и одно и тоже 64-битное число таким образом будет мапиться на разные пар 32-битных.


Это в теории, а на практике будет только x86/64 — либо i7, либо Xeon. А big endian я просто не буду поддерживать, как как для этого нужно во всем коде специально делать поддержку и тщательно его весь именно для этого тестировать, что совершенно не стоит потраченных усилий. Так же, как я не собираюсь поддерживать системы меньше 64 бит.

Просто мне не хочется писать код, который в явном виде нарушает strict aliasing и, таким образом, зависит от опций компиляции.
E>Тебе надо физически с битиками памяти работать, или таки нужны логически старшие и младшие биты?

Ну мне надо, например, параллельно сложить нижнее и верхнее 32-битные слова (нижнее с нижним, верхнее с верхним), так, чтобы при сложении нижнего не было переноса в верхнее. Но потом использовать это все как одно 64-битное слово.

E>А ещё есть второй вопрос, зачем ты хочешь, обязательно читать/писать память, а не двигать битики? Вдруг двигать битики быстрее? Например, во многих x86 процах смесь 32-битных и 64-битных инструкций дорогая...

E>Зачем ты хочешь мешать оптимизатору?

Просто не хочется слепо надеяться на оптимизатор и писать заведомо бессмысленные битовые операции. Профессиональным подходом здесь было бы сделать бенчмарк, пожалуй, и именно так я и сделаю в итоге.

Меня просто еще интересует концептуальная возможность обходить strict aliasing rule, так как оно является очень большим ограничением.

E>В общем, если ты хочешь работать с памятью напрямую, то есть речь о чём-то железячном, то пиши, читай прямо по адресам. Всё равно это никак не переносимо, а если таки речь идёт об операциях с числами, то бери сдвиги/маски и вперёд...


Ну отмена переносимости кода мало помогает, так как сама по себе не отменяет правила strict aliasing в компиляторах. А от опций и версий конкретных компиляторов не хочется зависеть.

На самом деле, вопрос "зачем" — это несколько другой вопрос (как обычно) и слегка оффтопик.

Меня интересует принципиальный вопрос обхода strict aliasing rule и, прежде всего, ответ на следующий вопрос:

Еще у меня была мысль про буфер char'ов: по стандарту любой тип можно алиазить массивом чаров, тогда что если записать этот в массив std::uint64_t, а прочитать два std::uint32_t — будет ли это нарушением strict aliasing rule? Очевидный ответ — да, поскольку читается один тип, а записывается другой. А может и нет. Этот момент мне неясен.

struct Foo
{
    alignas(std::uint64_t) char buffer[sizeof(std::uint64_t)];
};