Введите значение выравнивания и визуальный - PullRequest
0 голосов
/ 09 апреля 2019

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

Инициализатор предназначен для получения произвольного указателя памяти и создания экземпляра структуры на месте при условии соблюдения ограничений по размеру и выравниванию. Возвращает указатель на целевой тип.

Поскольку целевая структура объявлена, предполагается, что можно получить ограничение выравнивания. Это можно сделать с помощью alignof() (на C11) или offsetof() или с комбинацией sizeof(). См. этот предыдущий SO ответ по теме. Я протестировал все варианты, все они дают одинаковый результат.

Моя текущая проблема выглядит следующим образом: поскольку целевая структура содержит несколько полей long long, ее выравнивание, как ожидается, составит 8 байт в системах x64 и 4 байта в системах x86 (32-разрядных). Это уже известно: несмотря на то, что поля long long имеют длину 8 байт, 32-разрядные процессоры просто эмулируют 64-разрядные операции с кучей 32-разрядных, так что значение составляет всего 4 байта.

Если я проверяю ограничение выравнивания структуры, используя любой из вышеупомянутых методов, я получаю 8 на x64. На 32-битном x86 gcc и clang дают 4, тогда как Visual по-прежнему возвращает 8 .

ОК, первое удивление, я ожидал, что все компиляторы будут использовать одинаковые ограничения выравнивания и правила заполнения для данного ABI, и здесь Visual отличается. Но это становится более странным.

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

Теперь, используя Visual для 32-битной x86, инициализация завершается ошибкой половину времени, потому что структура фактически выровнена по границе 4 байта, а проверка возвращает 8 (это возвращаемое значение alignof()).

Это кажется странным. Я что-то пропустил или наблюдаю ошибку Visual?

...