Могу ли я использовать std :: align для выравнивания памяти с произвольными значениями 2? - PullRequest
0 голосов
/ 08 декабря 2018

Мне трудно интерпретировать следующее описание std::align из https://en.cppreference.com/w/cpp/memory/align

void* std::align(std::size_t alignment,
                 std::size_t size,
                 void*& ptr,
                 std::size_t& space );

Поведение не определено, если выравнивание не является фундаментальным или расширенным значением выравнивания, поддерживаемымреализация (до C ++ 17) степень двух (начиная с C ++ 17).

Если мое понимание верно, то это означает, что для C ++ 11 использование std::align является неопределенным поведением, еслиЗапрошенное вами выравнивание не соответствует выравниванию одного из встроенных типов C ++, таких как short, int, long, double, ....Следовательно, использование std::align со значением выравнивания, большим std::max_align_t (обычно это 8 или 16), вызывает неопределенное поведение.

Но теперь для C ++ 17 произошло изменение:

... степень двойки (начиная с C ++ 17).

Полагаю, это означает, что, начиная с C ++ 17, любое значение степени 2 является действительным выравниванием для std::align.

Кто-нибудь может это подтвердить?

Обновление:

Для реализаций std::align как GCC, так и LLVM любая степень 2 является действительным выравниванием.Для любых значений степени выравнивания, равных 2, реализации GCC и LLVM std::align вызывают неопределенное поведение.

Это, кажется, подтверждает мое предположение:

, поскольку в C ++ 17 любое значение степени 2 является действительным выравниванием для std :: align.

И я проверил, что даже для C ++ 11 std::align работает правильно для любого значения выравнивания степени 2, используя GCC, LLVM и MSVC.

1 Ответ

0 голосов
/ 08 декабря 2018

для C ++ 11 использование std :: align - неопределенное поведение, если запрошенное выравнивание не совпадает с выравниванием одного из встроенных типов C ++, таких как short, int, long, double, ....

Это не то, что говорит cppreference или стандарт .Начиная с C ++ 14 [ptr.align] /2.1:

alignment должно быть фундаментальным значением выравнивания или расширенным значением выравнивания, поддерживаемым реализацией в этом контексте

Фундаментальное выравнивание - это не выравнивание фундаментального типа.From [basic.align] / 2 :

Фундаментальное выравнивание представлено выравниванием, меньшим или равным наибольшему выравниванию, поддерживаемому реализацией во всех контекстах, которое являетсяравно alignof(std::max_align_t) (18,2).

Так что это просто так.В сочетании с утверждением [basic.align] / 4 о том, что все выравнивания должны иметь степень двойки, это означает, что фундаментальное выравнивание - это любое выравнивание, меньшее или равное alignof(std::max_align_t).

...