C ++ выравнивание класса - вызов члена по выровненному адресу - PullRequest
0 голосов
/ 26 ноября 2018

Я использую UBSAN и получаю следующую ошибку.Обратите внимание, что я компилирую clang 6.0.1 с -fsanitize = undefined.Я прочитал несколько справочных вопросов по SO и до сих пор не могу решить мою конкретную проблему.Вот справочные вопросы для справки:

Вот несколько замечаний по поводу класса C:

  • объект типа C создается с использованием new (C* o = new C();)
  • тип C имеет член типа A, который имеет 64-байтовое выравнивание.Я подтвердил это с помощью alignof.
  • C объявлено с использованием class alignas(64) C - но это не решает мою проблему

Моя текущая гипотеза заключается в том, что мне нужно использовать C ++11 эквивалент C ++ 17 std::aligned_alloc для создания объекта с использованием выровненного хранилища.Но я не уверен, как лучше всего это сделать или это действительно решит мою проблему.Я бы предпочел решить проблему один раз в определении класса C, а не всякий раз, когда я создаю C, если это возможно.Каков рекомендуемый подход к решению этой проблемы для устранения ошибки UBSAN?

1 Ответ

0 голосов
/ 26 ноября 2018

Если в вашем классе уже есть член, для которого требуется выравнивание по 64 байта, то класс также будет иметь выравнивание по 64 байта по необходимости.Таким образом, добавление явного alignas(64) на самом деле ничего не изменит.

Основная проблема здесь в том, что функции выделения (в C ++ 11) требуются только для возврата памяти, выровненной по фундаментальное выравнивание .C ++ 11 оставил его определяемым реализацией независимо от того, поддерживаются ли выровненные типы новыми или нет [expr.new] / 1 .C ++ 17 представил новые расширенные выравнивания и дополнительные функции выделения для решения этой проблемы (если и какие новые расширенные выравнивания поддерживаются, однако, все еще определяется реализацией).

ЕслиВы можете переключиться на компилятор, который поддерживает C ++ 17, скорее всего, ваш код будет просто работать.В противном случае вам, вероятно, придется либо использовать некоторую специфичную для реализации функцию для выделения выровненной памяти, либо просто свернуть собственное решение, например, на основе std :: align и размещения new (что будет работать в C ++ 11тоже) ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...