Почему в C ++ 11 не удаляется объект, имеющий деструктор с неопределенным поведением побочного эффекта? - PullRequest
9 голосов
/ 02 апреля 2012

Этот ответ цитаты C ++ 11 Standard 3.8:

если нет явного вызова деструктора или если выражение delete (5.3.5) не используется для освобождения хранилища, деструктор не должен вызываться неявно, и любая программа, которая зависит от побочных эффектов, создаваемых деструктор имеет неопределенное поведение.

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

Почему поведение программы сейчас не определено? Почему бы не пропустить побочные эффекты (поскольку деструктор не вызывается) и программа работает нормально, без применения побочных эффектов?

Ответы [ 4 ]

5 голосов
/ 02 апреля 2012

Важной частью является первая часть этого абзаца (выделено мной):

Программа может завершить время жизни любого объекта путем повторного использования хранилища, которое этот объект занимает ...

Если вы просто повторно используете хранилище для объекта, для деструктора которого был вызван , а не , то вы получите неопределенное поведение. Например, объект мог запустить поток, зарегистрировать обратный вызов или выполнить какое-либо другое действие, при котором внешний компонент мог бы ожидать, что объект все еще существует.

3 голосов
/ 02 апреля 2012

В этом случае у нас есть точный ответ. Специальная строка была введена для разрешения CWG 1116 , «Псевдоним членов профсоюза».

1 голос
/ 02 апреля 2012

Я полагаю, что это включено в стандарт для сбора мусора.И указать, что C ++ ведет себя иначе, чем некоторые другие языки, не вызывая деструкторы при сборе.

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

Если не не зависит от деструкторов, все в порядке.

1 голос
/ 02 апреля 2012

Ваш вопрос не имеет смысла.

Почему бы не пропустить побочные эффекты (так как деструктор не вызывается) и программа работает нормально, без применения побочных эффектов?

Они пропущены, потому что они были бы вызваны деструктором, и он не был вызван.

Мое чтение:

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

просто, я рассматриваю это в свете RAII. Пример:

#include "Object.hpp"

struct Manager: private boost::noncopyable {
  union Raw {
    char _[sizeof(Object)];
    Object o;
  };
  static Raw raw;

  Manager() { new (raw.o) Object(); }
  ~Manager() { raw.o.~Object(); }
};

Теперь, если я выделю Manager, забуду уничтожить его и выделю новый, я в затруднении, потому что я перезаписываю хранилище первого созданного Object вторым, даже если это все еще "жив". Это неопределенное поведение.

...