Задать вопрос
Dyikot
@Dyikot

Нарушается ли тут strict aliasing rule?

В следующим примере:
static Ref<T> FromThis(T* data)
{
    static_assert(alignof(T) <= alignof(RefMemoryBlockBase));
    return Ref(
        reinterpret_cast<RefMemoryBlockBase*>(
            reinterpret_cast<char*>(data) - sizeof(RefMemoryBlockBase)
        ), 
        data
    );
}


Структуры блоков памяти:
struct RefMemoryBlockBase
{
    virtual ~RefMemoryBlockBase() = default;

    std::atomic<uint32_t> References = 1;
};

template<typename T>
struct RefMemoryBlock : RefMemoryBlockBase
{
    template<typename... TArgs>
    RefMemoryBlock(TArgs&&... args):
        Value(std::forward<TArgs>(args)...)
    {}

    T Value;
};
  • Вопрос задан
  • 18 просмотров
Подписаться 1 Простой Комментировать
Помогут разобраться в теме Все курсы
  • Нетология
    Разработчик на C++
    12 месяцев
    Далее
  • Академия Эдюсон
    Разработчик игр на Unreal Engine + ИИ
    9 месяцев
    Далее
  • Stepik
    Профессия: Разработчик C++ (Junior)
    2 месяца
    Далее
Пригласить эксперта
Ответы на вопрос 1
opium
@opium
Просто люблю качественно работать
не совсем strict aliasing, тут UB другого рода. reinterpret_cast и вычитание sizeof(RefMemoryBlockBase) — уже нарушение арифметики указателей: результат выходит за границы подобъекта Value. Плюс класс с virtual деструктором не standard-layout, а стандарт разрешает компилятору переиспользовать tail padding базового класса под члены наследника, так что Value не обязан лежать ровно на sizeof(Base) байт. И это не гипотетика: на gcc 13 с atomic sizeof(Base)=16, а Value реально лежит на смещении 12. alignof-assert от этого не спасает.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы