Undefined поведение с не виртуальными деструкторами - это проблема реального мира?

Рассмотрим следующий код:

class A 
{
public:
  A() {}
  ~A() {}
};

class B: public A
{
  B() {}
  ~B() {}
};

A* b = new B;
delete b; // undefined behaviour

Я понимаю, что стандарт С++ говорит, что удаление b - это поведение undefined - то есть, все может случиться. Но в реальном мире, мой опыт заключается в том, что ~ A() вызывается всегда, и память правильно освобождена.

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

Очевидно, это не будет то, что вы хотите в нетривиальных случаях, но оно по крайней мере непротиворечиво. Знаете ли вы о какой-либо реализации на С++, где выше не выполняется, для показанного кода?

Ответ 1

Это бесконечный вопрос в теге С++: "Что такое предсказуемое поведение undefined". Легко решить все самостоятельно: получить каждую реализацию компилятора С++ и проверить, работает ли предсказуемая непредсказуемая работа. Это, тем не менее, то, что вы должны сделать сами.

Отправляйте назад то, что вы узнали, это было бы очень полезно знать. Пока непредсказуемое имеет последовательное и аннотированное поведение по всем направлениям. Это делает очень трудным для кого-то, кто пишет компилятор С++, чтобы заставить кого-нибудь обратить внимание на его продукт. Стандартизация по соглашению, часто происходит с языком, который имеет много undefined.

Ответ 2

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

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

Ответ 3

"Для показанного кода очень маловероятно, что вы когда-нибудь найдете реализацию, которая будет действовать. То есть, если мы исключим из рассмотрения различные" отладочные" реализации, которые специально и намеренно предназначены для обнаружения таких ошибок.

Ответ 4

Класс B почти всегда будет больше, чем A, в нетривиальных случаях, потому что в нем есть экземпляр A внутри него, а также дополнительные члены B. Это становится все хуже, когда вы вводите виртуальных членов.

Итак, в то время как ~ A будет вызвано, легко видеть, что такое поведение может привести к утечке памяти. Это поведение undefined не потому, что оно не может вызвать ~ A, что в основном гарантировано, а как управление памятью.