@Mercury13
Программист на «си с крестами» и не только

Сработает ли деструктор, присвоив atomic?

template <unsigned long long Rnd>
class DangleCanary {
public:
    DangleCanary() noexcept { value = rightCanary(); }
    ~DangleCanary() noexcept { value = 0; }

    DangleCanary(const DangleCanary&) noexcept {}
    DangleCanary& operator=(const DangleCanary&) noexcept { return *this; }
    void checkCanary() const;
private:
    std::atomic<uintptr_t> value = 0;
    uintptr_t rightCanary() const noexcept;
    static constexpr auto SCRAMBLE = static_cast<uintptr_t>(Rnd);
};

template <unsigned long long Rnd>
uintptr_t DangleCanary<Rnd>::rightCanary() const noexcept
    { return reinterpret_cast<uintptr_t>(this) ^ SCRAMBLE; }


template <unsigned long long Rnd>
void DangleCanary<Rnd>::checkCanary() const
{
    if (value != rightCanary())
        throw std::logic_error("[DangleCanary] Dangling link detected!");
}


Как вы понимаете, это простенький код для проверки, что данный объект существует и указатель на него не «повис в воздухе». Подобные штуки используются, когда имеем дело с тупыми указателями, проходящими через плохо контролируемую среду (QAbstractItemModel — ну или просто код, написанный неопытным прогером).

Меня конкретно интересует деструктор: может ли он «заоптимизировать» присваивание value = 0, убив весь смысл детектора висячего указателя?
  • Вопрос задан
  • 172 просмотра
Пригласить эксперта
Ответы на вопрос 1
wataru
@wataru Куратор тега C++
Разработчик на С++, экс-олимпиадник.
Не совсем понятно, а чего вы вообще пытаетесь добиться зануляя value? После деструктора весь объект и его член value уничтожаются. Любое обращение к ним - это UB. Соотвтественно вы этот новый 0 никак снаружи пощупать не сможете.

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

Единственный способ бороться с этим, кажется, это использовать умные указатели. Всякие WeakPtr, которые не уничтожают блок счетчиков при удалении объекта. Если же вы опустились до сырых указателей, то это тупо адрес (число). И просто по нему никак не понять, а что по этому адресу лежит - оригинальный объект или что-то левое.
Ответ написан
Ваш ответ на вопрос

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

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