Re: Обнуление указателей в деструкторе
От: Кодт Россия  
Дата: 04.06.09 10:44
Оценка: 2 (2) +5
Здравствуйте, Peter K., Вы писали:

PK>Насколько это pb = 0 может быть нужно и по какой причине?


1) Перестраховка. Обращение к деструированному объекту — это уже UB, только характер может меняться.
Диагностировать обращение к неожиданно нулевому указателю легче, чем к невалидному указателю куда-то в середину кучи.
В крайнем случае, быстро поймаешь ошибку защиты памяти. В противном случае, проедешься с бензопилой по чужим данным.


2) Либо неудачный/бездумный рефакторинг.
Написали reset, а потом обнаружили, что он используется лишь в деструкторе. И скопировали туда.
Либо наоборот — собрались писать reset и забросили, так и не выделив из деструктора.


3) Либо это лишь часть кода. А на деле там всё громоздче:
class A
{
    .......
    B* pb;
    .......
    
    void foo()
    {
        .....
        if(pb) .....
        .....
    }

    ~A()
    {
        .....
        foo();
        .....
        delete pb; pb = 0;
        .....
        foo();
        .....
    }
};

В роли foo() могут быть обратные вызовы каких-то союзнических функций, работающих с этим объектом.
Например, у тебя облако взаимосвязанных объектов, и запускается лавина рекурсивного удаления их всех.
(На мой взгляд, лавины — это дыра в архитектуре, но на скорую руку, бывает, терпимо).
... << RSDN@Home 1.2.0 alpha 4 rev. 1207>>
Перекуём баги на фичи!
Re: Обнуление указателей в деструкторе
От: Bell Россия  
Дата: 04.06.09 10:01
Оценка: 1 (1) +3 -2
Здравствуйте, Peter K., Вы писали:

PK>Насколько это pb = 0 может быть нужно и по какой причине?

Абсолютно излишнее действие.
Любите книгу — источник знаний (с) М.Горький
Re[3]: Обнуление указателей в деструкторе
От: Аноним  
Дата: 04.06.09 20:40
Оценка: +4
Здравствуйте, Ulitka, Вы писали:

U>А за "умные" указатели в иных местах и больно бьют.


Типа "обжегшись на молоке, дуют на воду"?
Ну есть такие, которые тупо отсекают многие полезные вещи.
Фанатизм и фундаментализм можно обсуждать долго, но уже не интересно.
Re[2]: Обнуление указателей в деструкторе
От: R.O. Prokopiev Россия http://127.0.0.1/
Дата: 04.06.09 10:26
Оценка: -2 :)
Здравствуйте, Bell, Вы писали:

PK>>Насколько это pb = 0 может быть нужно и по какой причине?

B>Абсолютно излишнее действие.

Нифига подобного.
Действие очень даже нужное.
Деструктор можно вызывать явно:

    A a;
    a.~A();
    a.~A();
Re: Обнуление указателей в деструкторе
От: jazzer Россия Skype: enerjazzer
Дата: 04.06.09 09:55
Оценка: 1 (1) +1
Здравствуйте, Peter K., Вы писали:

PK>Иногда приходится нечто подобное:


PK>
PK>class B;

PK>class A {
PK>   B * pb;
PK>public:
PK>   A() : pb(new B()) {}
PK>   ~A()
PK>   {
PK>      delete pb;
PK>      pb = 0;
PK>   }
PK>};
PK>

PK>Насколько это pb = 0 может быть нужно и по какой причине?
PK>(Извините, если уже было, не нашел).

Это так народ пытается нейтрализовать двойной вызов деструктора
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[2]: Обнуление указателей в деструкторе
От: Wo-o-olf Россия  
Дата: 04.06.09 10:17
Оценка: 1 (1) -1
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, Peter K., Вы писали:


PK>>Иногда приходится нечто подобное:


PK>>
PK>>class B;

PK>>class A {
PK>>   B * pb;
PK>>public:
PK>>   A() : pb(new B()) {}
PK>>   ~A()
PK>>   {
PK>>      delete pb;
PK>>      pb = 0;
PK>>   }
PK>>};
PK>>

PK>>Насколько это pb = 0 может быть нужно и по какой причине?
PK>>(Извините, если уже было, не нашел).

J>Это так народ пытается нейтрализовать двойной вызов деструктора


Ну до кучи ещё может быть попытка нейтрализовать использование уже невалидного указателя на A.


A * a = new A();
a->SomeMethod(); // method uses A::pb
delete a;
a->SomeMethod();
Re: Обнуление указателей в деструкторе
От: nen777w  
Дата: 04.06.09 09:26
Оценка: +1 -1
Я тоже так делаю, хотя смысла это не имеет.
Ну разве что переменная будет статическая.
Re[3]: Обнуление указателей в деструкторе
От: Кодт Россия  
Дата: 04.06.09 13:02
Оценка: +2
Здравствуйте, Peter K., Вы писали:

PK>Понятно. Т.е. никакого сакрального смысла для многопоточных приложений здесь нет.

PK>Обманули значит.

Видимо, те, кто тебя обманывал — пытались наобум исправить какой-то баг, связанный с гонками вокруг деструктора.
... << RSDN@Home 1.2.0 alpha 4 rev. 1207>>
Перекуём баги на фичи!
Re[5]: Обнуление указателей в деструкторе
От: Bell Россия  
Дата: 15.06.09 08:13
Оценка: +2
Здравствуйте, _wf, Вы писали:

B>>Просвяти, в каких это случаях оно такое нужное?


_wf>Г-н Саттер даёт следующий пример:


_wf>
_wf>void f()
_wf>{
_wf>    T t(1);
_wf>    T & rt = t;
_wf>    // <1> действия с t или rt
_wf>    t.~T();
_wf>    new (&t) T(2);
_wf>    // <2> действия с t или rt
_wf>    // автоуничтожение t
_wf>}
_wf>


_wf>И пишет, что данный код абсолютно легален и корректен до тех пор, пока есть

_wf>гарантия того, что выполнение "доберётся" до блока <2>:
_wf>если конструктор T(2) кинет исключение, будет автоматически вызван деструктор
_wf>для уже уничтоженного объекта

Опять не понял

12.4/14
...
the behavior is undefined if the destructor is invoked for an object whose lifetime has ended (3.8).
...


Я конечно понимаю, что в ряде случаев это самое неопределенное поведение является вполне определенным — но закладываться на это без крайней на то необходимости — не есть хорошо, ИМХО.
В данном случае, очевидно, ты имеешь ввиду то обстоятельство, что на некоторых платформах при обнулении указателя в первом вызове деструктора, при повторном вызове деструктора ничего страшного не произойдет. Как я уже сказал — повторный вызов деструктора — это уже UB, и лично меня совершенно не успокаивает тот факт, что в данный момент по счастливому стечению обстоятельств ничего не сломалось и не упало.
Любите книгу — источник знаний (с) М.Горький
Re[5]: Обнуление указателей в деструкторе
От: R1K0 Россия  
Дата: 04.06.09 14:36
Оценка: -1
В принципе все уже сказано. Но все равно добавлю
Я, например, всегда так делаю, ибо AV отладить куда проще, особенно если мозги позволили добавить в рогу создание crash-dump'ов.
При наличие того другого отладка кривых ручек становится необычайно легкой (в сравннии с тем самым UB).
Ибо UB — это попытка доказать, что ты и не хотел быть программистом, а, так, случайно зашел
Re[3]: Обнуление указателей в деструкторе
От: jazzer Россия Skype: enerjazzer
Дата: 07.06.09 13:21
Оценка: :)
Здравствуйте, Ulitka, Вы писали:

U>А за "умные" указатели в иных местах и больно бьют.


имя "иного места" в студию!
Народ должен знать, куда не отправлять резюме.
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[6]: Обнуление указателей в деструкторе
От: hramovnik  
Дата: 10.06.09 10:50
Оценка: :)
Здравствуйте, Bell, Вы писали:

B>Здравствуйте, hramovnik, Вы писали:


ROP>>>>Действие очень даже нужное.

B>>>Просвяти, в каких это случаях оно такое нужное?

H>> Например, если ты вернешь объект с указателем членом класса, то будет вызвано 2 дестр. Второй соответственно умрет, если нет обнуления.

B>Ничего не понял. Можно на примере?


Можно.

class A
{
public:
A(type *p = NULL)
   : ptr(p)
{};

~A()
{
 if(ptr)
 {
   delete ptr;
   ptr = NULL;
 }
};

type *ptr;
};

A some_function()
{
  A a(new type(/*init*/));
  /*some code*/
  return a;
}

void main()
{
  A a = some_function();
}
Re[7]: Обнуление указателей в деструкторе
От: Bell Россия  
Дата: 10.06.09 11:01
Оценка: +1
Здравствуйте, hramovnik, Вы писали:

B>>Ничего не понял. Можно на примере?

H>Можно.
...

Я почему-то именно про это и подумал
Скажи, как обнуление в одном экземпляре повлияет на другой экземпляр?

ЗЫ
Можно было бы хотя бы раз запустить примерчик-то...
Любите книгу — источник знаний (с) М.Горький
Обнуление указателей в деструкторе
От: Peter K.  
Дата: 04.06.09 09:23
Оценка:
Иногда приходится нечто подобное:

class B;

class A {
   B * pb;
public:
   A() : pb(new B()) {}
   ~A()
   {
      delete pb;
      pb = 0;
   }
};

Насколько это pb = 0 может быть нужно и по какой причине?
(Извините, если уже было, не нашел).
Re: Обнуление указателей в деструкторе
От: den123 Израиль http://den123.smugmug.com
Дата: 04.06.09 09:29
Оценка:
Здравствуйте, Peter K., Вы писали:

В данном случае нет никакого смысла обнулять, т.к. после деструктора уже ничего нет и последующее, ошибочное использование указателя уже будет невозможно
WBR — Yuriy
Re[2]: Обнуление указателей в деструкторе
От: Peter K.  
Дата: 04.06.09 09:49
Оценка:
Я когда-то читал, что так нужно в многопоточных программах.
Сейчас уже не вспомню где.
Re[2]: Обнуление указателей в деструкторе
От: Аноним  
Дата: 04.06.09 10:25
Оценка:
Здравствуйте, Bell, Вы писали:

B>Здравствуйте, Peter K., Вы писали:


PK>>Насколько это pb = 0 может быть нужно и по какой причине?

B>Абсолютно излишнее действие.

Не излишнее, см пост выше. После того как память освободилась, она не обнуляется, и если у тебя остался указатель на кусок памяти, где раньше жил объект, то ты можешь достучатся до полей мертвого объекта (с непредсказуемыми последствиями в дальнейшем). А если обнулишь, то сразу будет АВ шка.
Re[2]: Обнуление указателей в деструкторе
От: Peter K.  
Дата: 04.06.09 11:27
Оценка:
Понятно. Т.е. никакого сакрального смысла для многопоточных приложений здесь нет.
Обманули значит.
Re: Обнуление указателей в деструкторе
От: Аноним  
Дата: 04.06.09 11:45
Оценка:
PK>
PK>class B;

PK>class A {
PK>   B * pb;
PK>public:
PK>   A() : pb(new B()) {}
PK>   ~A()
PK>   {
PK>      delete pb;
PK>      pb = 0;
PK>   }
PK>};
PK>

PK>Насколько это pb = 0 может быть нужно и по какой причине?
PK>(Извините, если уже было, не нашел).

потому что кто нить потом может сделать например так:

class B;

class A {
   B * pb;
public:
   A() : pb(new B()) {}
   ~A()
   {
      delete pb;
      pb = 0;
      CleanupAll();
   }

   void CleanupAll()
   {
   ....
   pb->Cleanup();
   ...
   }
};

Tсли будет обнуление pb срузу после delete — то написанный кем то потом код сразу свалится в B::Cleanup() при обращении к данным/vftbl pb; А без обнуления будет UB — то бишь может свалится, может не свалится, может свалится потом, может свалится потом у каждого десятого юзера etc
Re[3]: Обнуление указателей в деструкторе
От: Bell Россия  
Дата: 04.06.09 12:24
Оценка:
Здравствуйте, R.O. Prokopiev, Вы писали:

B>>Абсолютно излишнее действие.


ROP>Нифига подобного.



ROP>Действие очень даже нужное.

Просвяти, в каких это случаях оно такое нужное?

ROP>Деструктор можно вызывать явно:

С этим никто не спорил
А вот обращение к полям разрушенного объекта — UB.

3.8/5
...
If the object will be or was of a non-POD class type, the program has undefined behavior if:
the pointer is used to access a non-static data member or call a non-static member function of the object

Любите книгу — источник знаний (с) М.Горький
Re[4]: Обнуление указателей в деструкторе
От: R.O. Prokopiev Россия http://127.0.0.1/
Дата: 04.06.09 14:12
Оценка:
Здравствуйте, Bell, Вы писали:

ROP>>Действие очень даже нужное.

B>Просвяти, в каких это случаях оно такое нужное?
Видел явный вызов деструктора в потрохах CArray
(еще в те времена когда не перешел на STL).
Глянул в VC8 — осталось.

Посмотрел в стандарт.
Признаться был не совсем прав.
Многократный вызов деструктора чреват UB.

12.4/14

Once a destructor is invoked for an object, the object no longer exists; the behavior is undefined if the
destructor is invoked for an object whose lifetime has ended (3.8). [ Example: if the destructor for an automatic
object is explicitly invoked, and the block is subsequently left in a manner that would ordinarily
invoke implicit destruction of the object, the behavior is undefined. ]

Re[2]: Обнуление указателей в деструкторе
От: Plague Россия  
Дата: 04.06.09 16:19
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Здравствуйте, Peter K., Вы писали:

PK>>Насколько это pb = 0 может быть нужно и по какой причине?

К>3) Либо это лишь часть кода. А на деле там всё громоздче:


Вот так хочешь людям поведать, где и почему оно может пригодится, а Кодт уже тут, как тут.
Думаю, что обнулять указатели стоит, даже в деструкторах. Вопрос лишь в том, не будет ли компилятор производить какие-либо оптимизации тут?
Re: Обнуление указателей в деструкторе
От: Аноним  
Дата: 04.06.09 19:32
Оценка:
Здравствуйте, Peter K., Вы писали:

PK>Насколько это pb = 0 может быть нужно и по какой причине?


Про то, что в случае проблем эти самые проблемы будет искать легче уже сказали.
Но лучше это дело автоматизировать и пользоваться умными указателями.
Re[3]: Обнуление указателей в деструкторе
От: Ulitka США http://lazarenko.me
Дата: 04.06.09 20:22
Оценка:
Здравствуйте, R.O. Prokopiev, Вы писали:

ROP>Здравствуйте, Bell, Вы писали:


PK>>>Насколько это pb = 0 может быть нужно и по какой причине?

B>>Абсолютно излишнее действие.

ROP>Нифига подобного.

ROP>Действие очень даже нужное.
ROP>Деструктор можно вызывать явно:

ROP>
ROP>    A a;
ROP>    a.~A();
ROP>    a.~A();
ROP>


Можно, конечно. А можно и явно два раза "delete pb;" сделать, тоже никто не запрещает.
Re[6]: Обнуление указателей в деструкторе
От: Ulitka США http://lazarenko.me
Дата: 04.06.09 20:24
Оценка:
Здравствуйте, R1K0, Вы писали:

RK>AV отладить куда проще


А вот и нет. Точно так же просто, как и обращение к уже "удаленному" сегменту памяти.
Re[2]: Обнуление указателей в деструкторе
От: Ulitka США http://lazarenko.me
Дата: 04.06.09 20:26
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Peter K., Вы писали:


PK>>Насколько это pb = 0 может быть нужно и по какой причине?


А>Про то, что в случае проблем эти самые проблемы будет искать легче уже сказали.

А>Но лучше это дело автоматизировать и пользоваться умными указателями.

А за "умные" указатели в иных местах и больно бьют.
Re: Обнуление указателей в деструкторе
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 05.06.09 20:08
Оценка:
Здравствуйте, Peter K., Вы писали:

PK>Иногда приходится нечто подобное:


PK>Насколько это pb = 0 может быть нужно и по какой причине?

PK>(Извините, если уже было, не нашел).

В далеком детстве, я как-то раз раступил на грабли BCB, которые дважды вызывал деструктор статического объекта. До сих пор вспоминаю, и, из вариантов — обнулять / не обнулять, выбираю — обнулять

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

----
К проблемам многопоточного кода это имеет очень косвенное отношение.
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[3]: Обнуление указателей в деструкторе
От: yarus23  
Дата: 07.06.09 11:24
Оценка:
U>А за "умные" указатели в иных местах и больно бьют.

Это где же бьют за boost::scoped_ptr, скажи, я туда ни за что не пойду работать.
Re[4]: Обнуление указателей в деструкторе
От: hramovnik  
Дата: 10.06.09 10:11
Оценка:
Здравствуйте, Bell, Вы писали:

ROP>>Действие очень даже нужное.

B>Просвяти, в каких это случаях оно такое нужное?

Например, если ты вернешь объект с указателем членом класса, то будет вызвано 2 дестр. Второй соответственно умрет, если нет обнуления.
Re[5]: Обнуление указателей в деструкторе
От: Bell Россия  
Дата: 10.06.09 10:24
Оценка:
Здравствуйте, hramovnik, Вы писали:

ROP>>>Действие очень даже нужное.

B>>Просвяти, в каких это случаях оно такое нужное?

H> Например, если ты вернешь объект с указателем членом класса, то будет вызвано 2 дестр. Второй соответственно умрет, если нет обнуления.

Ничего не понял. Можно на примере?
Любите книгу — источник знаний (с) М.Горький
Re[3]: Обнуление указателей в деструкторе
От: mike_rs Россия  
Дата: 10.06.09 11:01
Оценка:
Здравствуйте, Plague, Вы писали:

P>Вот так хочешь людям поведать, где и почему оно может пригодится, а Кодт уже тут, как тут.

P>Думаю, что обнулять указатели стоит, даже в деструкторах. Вопрос лишь в том, не будет ли компилятор производить какие-либо оптимизации тут?

кстати компилер вполне может выкинуть такой код. Вспомнился Шнайер (?) с примеров когда в функции шифрование перед выходом обнулялся ключ через memset, типа чтобы все секурно и на стеке не оставить данные, а умный компилер, видя что к обнуляемым локальным данным дальше обрашений нет выкидывал этот memset. В некоторых криптолибах это дело специальным образом обходится.
Re[7]: Обнуление указателей в деструкторе
От: Caracrist https://1pwd.org/
Дата: 10.06.09 11:14
Оценка:
Здравствуйте, hramovnik, Вы писали:

H>Здравствуйте, Bell, Вы писали:


B>>Здравствуйте, hramovnik, Вы писали:


ROP>>>>>Действие очень даже нужное.

B>>>>Просвяти, в каких это случаях оно такое нужное?

H>>> Например, если ты вернешь объект с указателем членом класса, то будет вызвано 2 дестр. Второй соответственно умрет, если нет обнуления.

B>>Ничего не понял. Можно на примере?


H>Можно.


H>
H>class A
H>{
H>public:
H>A(type *p = NULL)
H>   : ptr(p)
H>{};

H>~A()
H>{
H> if(ptr)
H> {
H>   delete ptr;
H>   ptr = NULL;
H> }
H>};

H>type *ptr;
H>};

H>A some_function()
H>{
H>  A a(new type(/*init*/));
H>  /*some code*/
H>  return a;
H>}

H>void main()
H>{
H>  A a = some_function();
H>}
H>


второй умрёт даже если было обнуление.
Значение указателя скопируется в другой объект ещё до обнуления, и в деструкторе второго будет пытаться удалить уже удалённый объект.
Два деструктора сами по себе(не явно) никогда не вызовутся.
~~~~~
~lol~~
~~~ Single Password Solution
Re: Обнуление указателей в деструкторе
От: Kingofastellarwar Украина  
Дата: 10.06.09 12:22
Оценка:
Здравствуйте, Peter K., Вы писали:

PK>Иногда приходится нечто подобное:


PK>
PK>class B;

PK>class A {
PK>   B * pb;
PK>public:
PK>   A() : pb(new B()) {}
PK>   ~A()
PK>   {
PK>      delete pb;
PK>      pb = 0;
PK>   }
PK>};
PK>

PK>Насколько это pb = 0 может быть нужно и по какой причине?
PK>(Извините, если уже было, не нашел).

иногда надо, и с таким сталкивался, когда в деструкторе стоит эвент говорящий что объект уничтожается, а обработчик может обратится к этой переменной, а то и косвенно вызвать деструктор еще раз
Я изъездил эту страну вдоль и поперек, общался с умнейшими людьми и я могу вам ручаться в том, что обработка данных является лишь причудой, мода на которую продержится не более года. (с) Эксперт, авторитет и профессионал из 1957 г.
Re[7]: Обнуление указателей в деструкторе
От: ffk  
Дата: 11.06.09 06:38
Оценка:
Здравствуйте, Ulitka, Вы писали:

U>Здравствуйте, R1K0, Вы писали:


RK>>AV отладить куда проще


U>А вот и нет. Точно так же просто, как и обращение к уже "удаленному" сегменту памяти.

Для релиза не факл, а AV 100%
Re[2]: Обнуление указателей в деструкторе
От: ffk  
Дата: 11.06.09 06:42
Оценка:
Здравствуйте, Kingofastellarwar, Вы писали:

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


Ужас! А как же нормальная синхронизация?
Re[3]: Обнуление указателей в деструкторе
От: Коваленко Дмитрий Россия http://www.ibprovider.com
Дата: 11.06.09 07:53
Оценка:
Здравствуйте, ffk, Вы писали:

ffk>Здравствуйте, Kingofastellarwar, Вы писали:


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


ffk>Ужас! А как же нормальная синхронизация?


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

До кучи (для упрощения выискивания причины падений) нужно завести флаг о котором я тут раньше упомянул ...

Вот, надыбал в мемуарах
TREGDataContainer::~TREGDataContainer()
{
 DEBUG_CODE(m_sobj_is_destroyed=true);

 this->ResetHandlers();

 //отключаемся от уведомлений вложенных объектов
 Folders              .ResetHandlers();
 Persons              .ResetHandlers();
 Things               .ResetHandlers();
 PersonDealRefs       .ResetHandlers();
 ThingDealRefs        .ResetHandlers();
 CommonDocuments      .ResetHandlers();
 Units                .ResetHandlers();
 Deals                .ResetHandlers();
 UnitDealLinks        .ResetHandlers();
 UnitRightLinks       .ResetHandlers();
 DealCMDocLinks       .ResetHandlers();
 UnitCMDocLinks       .ResetHandlers();

 CurrentDeal          .ResetHandlers();
 CurrentThingDealRef  .ResetHandlers();

 DESTROY_COMPONENT()
}//~TREGDataContainer

void TREGDataContainer::ResetHandlers()
{
 OnDataChange                =NULL;
 OnCMDocumentChange          =NULL;
 OnDealChange                =NULL;
 OnUnitChange                =NULL;

 OnCurrentThingDealRefChange =NULL;
}//ResetHandlers
-- Пользователи не приняли программу. Всех пришлось уничтожить. --
Re[4]: Обнуление указателей в деструкторе
От: _wf Россия  
Дата: 15.06.09 07:28
Оценка:
ROP>>Действие очень даже нужное.
B>Просвяти, в каких это случаях оно такое нужное?

Г-н Саттер даёт следующий пример:

void f()
{
    T t(1);
    T & rt = t;
    // <1> действия с t или rt
    t.~T();
    new (&t) T(2);
    // <2> действия с t или rt
    // автоуничтожение t
}


И пишет, что данный код абсолютно легален и корректен до тех пор, пока есть
гарантия того, что выполнение "доберётся" до блока <2>:
если конструктор T(2) кинет исключение, будет автоматически вызван деструктор
для уже уничтоженного объекта
Re[6]: Обнуление указателей в деструкторе
От: _wf Россия  
Дата: 16.06.09 08:18
Оценка:
_wf>>
_wf>>void f()
_wf>>{
_wf>>    T t(1);
_wf>>    T & rt = t;
_wf>>    // <1> действия с t или rt
_wf>>    t.~T();
_wf>>    new (&t) T(2);
_wf>>    // <2> действия с t или rt
_wf>>    // автоуничтожение t
_wf>>}
_wf>>


B>Опять не понял

B>

B>12.4/14
B>...
B>the behavior is undefined if the destructor is invoked for an object whose lifetime has ended (3.8).
B>...


Противоречия стандарта вышеприведённому коду не вижу. Время жизни объекта t, объявленного в первой строке функции,
заканчивается (с точки зрения компилятора) перед выходом из функции. Компилятор исправно выполняет свою работу
(а именно — разрушение объекта) как при нормальном, так и при "исключительном" выходе из функции.

Противоречие в том, что в середине функции объект искуственно переконструируется (но это проблема разработчика,
а не компилятора, и выбор такого решения исключительно на совести первого), и, если повторное конструирование
не удаётся (конструктор выбрасывает исключение), происходит, по сути, двойной вызов деструктора.
И в данном конкретном случае, проверка на повторный вызов деструктора будет весьма кстати. Остальное дело
десятое.

Всё это не отменяет того, что для того, чтобы написать подобное, нужны действительно веские причины и полное
понимание нюансов и путей выполнения. Проверка "на всякий случай" имхо — вопрос спорный.
Re[7]: Обнуление указателей в деструкторе
От: Bell Россия  
Дата: 16.06.09 09:20
Оценка:
Здравствуйте, _wf, Вы писали:

_wf>Противоречия стандарта вышеприведённому коду не вижу.

Об этом вроде никто и не говорил
_wf>Время жизни объекта t, объявленного в первой строке функции,
_wf>заканчивается (с точки зрения компилятора) перед выходом из функции. Компилятор исправно выполняет свою работу
_wf>(а именно — разрушение объекта) как при нормальном, так и при "исключительном" выходе из функции.

_wf>Противоречие в том, что в середине функции объект искуственно переконструируется

В С++ нет такого понятоя — "переконструирование объекта".

_wf>...(но это проблема разработчика,

_wf>а не компилятора, и выбор такого решения исключительно на совести первого), и, если повторное конструирование
_wf>не удаётся (конструктор выбрасывает исключение), происходит, по сути, двойной вызов деструктора.
По сути происходит принудительное окончание времени жизни объекта при явном вызове деструктора. Если конструирование нового объекта на месте старого прошло неудачно, то мы имеем вызов деструктора для уже мертвого объекта — UB.

_wf>И в данном конкретном случае, проверка на повторный вызов деструктора будет весьма кстати. Остальное дело

_wf>десятое.
Если считать нормальной ситуацией неопределенное поведение программы — то действительно, все это дело десятое. В добрый путь.
Любите книгу — источник знаний (с) М.Горький
Re[8]: Обнуление указателей в деструкторе
От: _wf Россия  
Дата: 16.06.09 12:16
Оценка:
Здравствуйте, Bell, Вы писали:

B>Здравствуйте, _wf, Вы писали:


_wf>>Противоречия стандарта вышеприведённому коду не вижу.

B>Об этом вроде никто и не говорил
_wf>>Время жизни объекта t, объявленного в первой строке функции,
_wf>>заканчивается (с точки зрения компилятора) перед выходом из функции. Компилятор исправно выполняет свою работу
_wf>>(а именно — разрушение объекта) как при нормальном, так и при "исключительном" выходе из функции.

_wf>>Противоречие в том, что в середине функции объект искуственно переконструируется

B>В С++ нет такого понятоя — "переконструирование объекта".

Никто и не говорит про понятия C++ — придираться к словам не обязательно.
Мог написать вашим штилем —
"происходит принудительное окончание времени жизни объекта при явном вызове деструктора"
как в этом ключе завернуть про его reborn даже не знаю.

_wf>>...(но это проблема разработчика,

_wf>>а не компилятора, и выбор такого решения исключительно на совести первого), и, если повторное конструирование
_wf>>не удаётся (конструктор выбрасывает исключение), происходит, по сути, двойной вызов деструктора.
B>По сути происходит принудительное окончание времени жизни объекта при явном вызове деструктора. Если конструирование нового объекта на месте старого прошло неудачно, то мы имеем вызов деструктора для уже мертвого объекта — UB.

Вполне предсказуемое такое U/B, соответственно, может быть проконтроллировано.

_wf>>И в данном конкретном случае, проверка на повторный вызов деструктора будет весьма кстати. Остальное дело

_wf>>десятое.
B>Если считать нормальной ситуацией неопределенное поведение программы — то действительно, все это дело десятое. В добрый путь.

Моё отношение к ситуации, в общем-то, было в последнем абзаце.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.