BCB 6.0 - глючит даже RAII !
От: Аноним  
Дата: 05.05.08 14:11
Оценка:
Нашел еще один глюк у BCB6.0 нарушающий основополагающий принцип — RAII:

#include <iostream>
#include <memory>


using namespace std;


class Outer
{
public:
    ~Outer()
    {
        cout << "~Outer" << endl;
    }
};

class Inner
{
public:
    Inner()
    {
        throw 1;
    }
    ~Inner()
    {
        cout << "~Inner" << endl;
    }
};

int main()
{
    try
    {
        auto_ptr<Outer> outer(new Outer());
        auto_ptr<Inner> inner(new Inner());
    }
    catch (...)
    {
        cin.get();
    }
}

ни за что не угадаете, что в результате:
~Inner




з.ы. естественно проверил (copy/paste) в gcc — там усе как нада — ~Outer
з.ы2. как такое вообще возможно?
Re: BCB 6.0 - глючит даже RAII !
От: dotidot Россия  
Дата: 05.05.08 14:15
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Нашел еще один глюк у BCB6.0 нарушающий основополагающий принцип — RAII:


А>int main()

А>{
А> try
А> {
А> auto_ptr<Outer> outer(new Outer());
А> auto_ptr<Inner> inner(new Inner());
А> }
А> catch (...)
А> {
А> cin.get();
А> }
А>}
А>[/ccode]

а это только в main е так выходит? если это скопипастить в f() и f из main вызвать поведение будет тоже?
Re[2]: BCB 6.0 - глючит даже RAII !
От: Аноним  
Дата: 05.05.08 14:18
Оценка:
Здравствуйте, dotidot, Вы писали:

D>а это только в main е так выходит? если это скопипастить в f() и f из main вызвать поведение будет тоже?


везде,.. не поверите — в рабочем проекте(!) такое открылось. я не в шоке — я в а%уе.

скажите, как с этим жить?
Re[3]: BCB 6.0 - глючит даже RAII !
От: don ASKet Россия  
Дата: 05.05.08 14:32
Оценка:
Здравствуйте, Аноним, Вы писали:

А>скажите, как с этим жить?


нда, дела...

апдейт ставил? помнится еще когда билдер жив был, под него один точно был... что уже правил точно не помню ... попробуй поискать, может где в сети завалялось, а то на борлондовом сайте, вроде как глухо..
или вот еще вариант, откатится к 5-ке если уже так билдер нужен
Меняю два проигрывателя, на один выигрватель! Возможна доплата... ;)
Re[4]: BCB 6.0 - глючит даже RAII !
От: Аноним  
Дата: 05.05.08 14:36
Оценка:
Здравствуйте, don ASKet, Вы писали:

DA>нда, дела...


DA>апдейт ставил? помнится еще когда билдер жив был, под него один точно был... что уже правил точно не помню ... попробуй поискать, может где в сети завалялось, а то на борлондовом сайте, вроде как глухо..

DA>или вот еще вариант, откатится к 5-ке если уже так билдер нужен

последний, вроде, апдейт стоит (BCB6_ENT_Update_4.exe).
я, конечно, знаю что дебилдер — гумно, но то, что это даже не объектно-ориентированный язык — для меня открытие
Re: BCB 6.0 - глючит даже RAII !
От: Аноним  
Дата: 05.05.08 14:57
Оценка:
А>з.ы. естественно проверил (copy/paste) в gcc — там усе как нада — ~Outer
А>з.ы2. как такое вообще возможно?
Проверил — таки да. Помнится я за ним еще видел забавные глюки с исполльзованием тернарного оператора и строк в нем. Глюки были в том что память не освобождалась отведенная, тк почемуто не вызывался деструктор временной переменной внутри тернарного оператора. Ща точно не воспоизведу код, тк давно это было...
Re: BCB 6.0 - глючит даже RAII !
От: Mr.Cat  
Дата: 05.05.08 15:47
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Нашел еще один глюк у BCB6.0 нарушающий основополагающий принцип — RAII:

А>ни за что не угадаете, что в результате:
А>
А>~Inner
А>


Возможно, это ошибка в реализации auto_ptr? Пробовали без него?
Re: BCB 6.0 - глючит даже RAII !
От: Аноним  
Дата: 05.05.08 16:15
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Нашел еще один глюк у BCB6.0 нарушающий основополагающий принцип — RAII:


...

А>ни за что не угадаете, что в результате:

А>
А>~Inner
А>


Это наверное типа совместимость с Delphi, там исключение в конструкторе приводит к вызову деструктора.
Правда тогда всё равно непонятно, чего не ~Inner ~Outer а просто ~Inner
Re: BCB 6.0 - глючит даже RAII !
От: Left2 Украина  
Дата: 05.05.08 16:50
Оценка:
А попробуй сделать деструктор Inner виртуальным — думаю, оно вообще должно грохнуться с GPF.
Сдаётся мне что это отрабатывает деструктор auto_ptr<Inner> inner, при чём inner ещё и не инициализирован, так что this в деструкторе Inner вообще состоит из мусора.
... << RSDN@Home 1.2.0 alpha rev. 717>>
Re: BCB 6.0 - глючит даже RAII !
От: srggal Украина  
Дата: 05.05.08 20:33
Оценка:
Здравствуйте, Аноним, Вы писали:

А если заменить на:
А>
....
А>int main()
А>{
А>    try
А>    {
        auto_ptr<Outer> outer;
                outer.reset( new Outer );
        auto_ptr<Inner> inner;
                inner.reset(new Inner());
А>    }
А>    catch (...)
А>    {
А>        cin.get();
А>    }
А>}
А>


Что нить изменится?
Re[2]: BCB 6.0 - глючит даже RAII !
От: Аноним  
Дата: 06.05.08 06:16
Оценка:
Здравствуйте, Mr.Cat, Вы писали:

MC>Возможно, это ошибка в реализации auto_ptr? Пробовали без него?

без него не пробовал, но ошибки в реализации не нашел (STLPort):
explicit auto_ptr(_Tp* __px) { this->__set(__px); }
void  __set(void* __p) { _M_p = __p; }
~auto_ptr() { /* boris : reset(0) might be better */ delete this->get(); }


з.ы. с одним объектом и генерацией исключения в конструкторе все работает как надо.
з.ы2. попробовал, как тут посоветовали использовать не конструктор для инициализации, а reset — все работает как надо.
Re[2]: BCB 6.0 - глючит даже RAII !
От: Аноним  
Дата: 06.05.08 06:21
Оценка:
Здравствуйте, srggal, Вы писали:

А>>
S>        auto_ptr<Outer> outer;
S>                outer.reset( new Outer );
S>        auto_ptr<Inner> inner;
S>                inner.reset(new Inner());
А>>

S>Что нить изменится?
в корне . так все работает...
Re[2]: BCB 6.0 - глючит даже RAII !
От: Аноним  
Дата: 06.05.08 06:27
Оценка:
Здравствуйте, Left2, Вы писали:

L>А попробуй сделать деструктор Inner виртуальным — думаю, оно вообще должно грохнуться с GPF.

L>Сдаётся мне что это отрабатывает деструктор auto_ptr<Inner> inner, при чём inner ещё и не инициализирован, так что this в деструкторе Inner вообще состоит из мусора.

ну угадали!..
тут все гораздо хуже!
#include <iostream>
#include <memory>

using namespace std;

class Base
{
public:
    virtual ~Base()
    {
        cout << "~Base" << endl;
    }
};

class Outer : public Base
{
public:
    ~Outer()
    {
        cout << "~Outer" << endl;
    }
};

class Inner : public Base
{
public:
    Inner()
    {
        throw 1;
    }
    ~Inner()
    {
        cout << "~Inner" << endl;
    }
};

int main()
{
    try
    {
        auto_ptr<Outer> outer(new Outer());
        auto_ptr<Inner> inner(new Inner());
    }
    catch (...)
    {
        cin.get();
    }
}

что получаем в результате?

~Base
~Base

Re[3]: BCB 6.0 - глючит даже RAII !
От: srggal Украина  
Дата: 06.05.08 06:56
Оценка:
Здравствуйте, Аноним, Вы писали:

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


А>>>
S>>        auto_ptr<Outer> outer;
S>>                outer.reset( new Outer );
S>>        auto_ptr<Inner> inner;
S>>                inner.reset(new Inner());
А>>>

S>>Что нить изменится?
А>в корне . так все работает...

чтд.
ЗЫ
Лефт2 грил немного о другом, не о

А>
..
А>class Inner : public Base
..
А>


Но, о:

...
А>class Inner
{
...
virtual ~Inner()
...
}
Re[4]: BCB 6.0 - глючит даже RAII !
От: Left2 Украина  
Дата: 06.05.08 07:25
Оценка:
S>чтд.
S>ЗЫ
S>Лефт2 грил немного о другом, не о

S>Но, о:


Вообще-то да.
Но и так сойдёт — у Base деструктор виртуальный, так что если бы в inner был мусор, то оно бы тоже грохнулось и в таком варианте.
Так что идея моя похоже не прокатила Надо бы вывести значения this в деструкторе, да и отладчиком/дизассемблером посмотреть что там этот суперкомпилятор нагенерил. Всё же интересно от чего ему так сносит башню.
... << RSDN@Home 1.2.0 alpha rev. 717>>
Re[5]: BCB 6.0 - глючит даже RAII !
От: srggal Украина  
Дата: 06.05.08 07:33
Оценка:
Здравствуйте, Left2, Вы писали:

S>>чтд.

S>>ЗЫ
S>>Лефт2 грил немного о другом, не о

S>>Но, о:


L>Вообще-то да.

L>Но и так сойдёт — у Base деструктор виртуальный, так что если бы в inner был мусор, то оно бы тоже грохнулось и в таком варианте.
L>Так что идея моя похоже не прокатила Надо бы вывести значения this в деструкторе, да и отладчиком/дизассемблером посмотреть что там этот суперкомпилятор нагенерил. Всё же интересно от чего ему так сносит башню.

Насколько я понимаю, то, если реализация std::auto_ptr корректна — то

auto_ptr<Inner> inner(new Inner());

Генерится код — который никак не расчитывает на генерацию исключения, скажем, как вариант аналог глюков с оптимизацией у MSVC 6 при недекларированных исключениях (сумбурно, но не вспомнил ключ командной строки).

если в конструкторе Inner декларировать исключение — что нить изменится?

ЗЫ
Сорри, нет ни Билдера ни даже винды под рукой
Re[4]: BCB 6.0 - глючит даже RAII !
От: Аноним  
Дата: 06.05.08 07:34
Оценка:
Здравствуйте, srggal, Вы писали:

S>Лефт2 грил немного о другом, не о


А>>
S>..
А>>class Inner : public Base
S>..
А>>


S>Но, о:


S>
S>...
А>>class Inner
S>{
S>...
S>virtual ~Inner()
S>...
S>}
S>


так тоже пробовал но решил усложнить пример после того как небыло GPF
Re[6]: BCB 6.0 - глючит даже RAII !
От: Аноним  
Дата: 06.05.08 07:42
Оценка:
Здравствуйте, srggal, Вы писали:

S>Насколько я понимаю, то, если реализация std::auto_ptr корректна — то

корректна, в одном из постов приводил выдержки из нее... — детерминированное удаление хранимого указателя в деструкторе


S>Генерится код — который никак не расчитывает на генерацию исключения, скажем, как вариант аналог глюков с оптимизацией у MSVC 6 при недекларированных исключениях (сумбурно, но не вспомнил ключ командной строки).

тож предпологал — включал фулдебаг и т.п.

S>если в конструкторе Inner декларировать исключение — что нить изменится?

всмысле указать спецификацию исключений ктора?
Inner() throw (int)

поведение не изменилось

S>Сорри, нет ни Билдера ни даже винды под рукой

везет вам
Re[7]: BCB 6.0 - глючит даже RAII !
От: srggal Украина  
Дата: 06.05.08 07:49
Оценка:
Здравствуйте, Аноним, Вы писали:

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


S>>если в конструкторе Inner декларировать исключение — что нить изменится?

А>всмысле указать спецификацию исключений ктора?
А>
А>Inner() throw (int)
А>

А>поведение не изменилось

Если сформулировать вкратце — проблема похоже в том, что Inner после генерации исключения трактуется из конструктора как полностью сконструированный.

Можно попробовать упростиь
try
А>    {
        Outer outer( new Outer );
        Inner inner(new Inner());
А>    }
А>    catch (...)
А>    {
А>        cin.get();
А>    }

Что изменится?

После чего, собственно можно начинать изучать кодогенерацию неработающего примера.
Re[8]: BCB 6.0 - глючит даже RAII !
От: Аноним  
Дата: 06.05.08 08:45
Оценка:
Здравствуйте, srggal, Вы писали:

S>Если сформулировать вкратце — проблема похоже в том, что Inner после генерации исключения трактуется из конструктора как полностью сконструированный.

это пол беды, не удаляется при этом полностью сконструированный объект — outer

S>Можно попробовать упростиь

    try
    {
        Outer outer;
        Inner inner;
    }
    catch (...)
    {
        cin.get();
    }

так работает
~Outer
Re[8]: BCB 6.0 - глючит даже RAII !
От: srggal Украина  
Дата: 06.05.08 11:52
Оценка:
Здравствуйте, srggal, Вы писали:

S>Можно попробовать упростиь

S>
S>try
А>>    {
S>        Outer outer;
S>        Inner inner(new Inner());
А>>    }
А>>    catch (...)
А>>    {
А>>        cin.get();
А>>    }
S>

S>Что изменится?

В предложение вкралась неточность — исправил на выделенное.
Будет ли BCB разрушать иннер?
Re[9]: BCB 6.0 - глючит даже RAII !
От: Аноним  
Дата: 06.05.08 12:22
Оценка:
Здравствуйте, srggal, Вы писали:

S>В предложение вкралась неточность — исправил на выделенное.

S>Будет ли BCB разрушать иннер?

да, старый баг

~Inner
Re[10]: BCB 6.0 - глючит даже RAII !
От: srggal Украина  
Дата: 06.05.08 12:53
Оценка:
Здравствуйте, Аноним, Вы писали:

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


S>>Будет ли BCB разрушать иннер?


А>да, старый баг


А>
А>~Inner
А>


теперь попробуем понять, что именно он разрушает:
S>>
S>>try
А>>>    {
S>>        Outer outer;
S>>        Inner* pinner = new Inner();
А>>>    }
А>>>    catch (...)
А>>>    {
А>>>        cin.get();
А>>>    }
S>>


Что изменится?
ЗЫ
Может пора уже вам выложить сгенеренный asm?
Re[11]: BCB 6.0 - глючит даже RAII !
От: Аноним  
Дата: 06.05.08 13:12
Оценка:
Здравствуйте, srggal, Вы писали:

S>>>
S>>>        Outer outer;
S>>>        Inner* pinner = new Inner();
S>>>

S>Что изменится?
в лучшую сторону т.е. так работает как надо.

S>Может пора уже вам выложить сгенеренный asm?

легко:
Unit1.cpp.34: auto_ptr<Outer> outer(new Outer());
00401181 66C745E01400     mov word ptr [ebp-0x20],0x0014
00401187 6A08             push 0x08
00401189 E85C0F0000       call CC3260.operator new(unsigned int)
0040118E 59               pop ecx
0040118F 50               push eax
00401190 8D55FC           lea edx,[ebp-0x04]
00401193 52               push edx
00401194 E8AF000000       call _STL::auto_ptr<Outer>::auto_ptr<Outer>(Outer *)
00401199 83C408           add esp,0x08
0040119C FF45EC           inc dword ptr [ebp-0x14]
0040119F 66C745E02000     mov word ptr [ebp-0x20],0x0020
Unit1.cpp.35: auto_ptr<Inner> inner(new Inner());
004011A5 66C745E02C00     mov word ptr [ebp-0x20],0x002c
004011AB 6A08             push 0x08
004011AD E8380F0000       call CC3260.operator new(unsigned int)
004011B2 59               pop ecx
004011B3 8945F4           mov [ebp-0x0c],eax
004011B6 85C0             test eax,eax
004011B8 741A             jz +0x1a
004011BA 66C745E03800     mov word ptr [ebp-0x20],0x0038
004011C0 FF75F4           push dword ptr [ebp-0x0c]
004011C3 E800010000       call Inner::Inner()
004011C8 59               pop ecx
004011C9 66C745E02C00     mov word ptr [ebp-0x20],0x002c
004011CF 8B55F4           mov edx,[ebp-0x0c]
004011D2 EB03             jmp +0x03
004011D4 8B55F4           mov edx,[ebp-0x0c]
004011D7 52               push edx
004011D8 8D45F8           lea eax,[ebp-0x08]
004011DB 50               push eax
004011DC E837010000       call _STL::auto_ptr<Inner>::auto_ptr<Inner>(Inner *)
004011E1 83C408           add esp,0x08
004011E4 FF45EC           inc dword ptr [ebp-0x14]
004011E7 66C745E02000     mov word ptr [ebp-0x20],0x0020
Unit1.cpp.36: }
004011ED FF4DEC           dec dword ptr [ebp-0x14]
004011F0 6A02             push 0x02
004011F2 8D4DF8           lea ecx,[ebp-0x08]
004011F5 51               push ecx
004011F6 E855010000       call _STL::auto_ptr<Inner>::~auto_ptr<Inner>()
004011FB 83C408           add esp,0x08
004011FE FF4DEC           dec dword ptr [ebp-0x14]
00401201 6A02             push 0x02
00401203 8D45FC           lea eax,[ebp-0x04]
00401206 50               push eax
00401207 E874000000       call _STL::auto_ptr<Outer>::~auto_ptr<Outer>()
0040120C 83C408           add esp,0x08
0040120F 66C745E00800     mov word ptr [ebp-0x20],0x0008
00401215 66C745E00000     mov word ptr [ebp-0x20],0x0000
0040121B EB17             jmp +0x17
Unit1.cpp.39: cin.get();
...
Re: bcc32 5.5.1 - тоже самое
От: TailWind  
Дата: 06.05.08 14:31
Оценка:
Результат
~Inner


Тоже есть ошибка!!!
Re[2]: bcc32 5.5.1 - тоже самое
От: TailWind  
Дата: 06.05.08 14:33
Оценка:
Я давно заметил, что при некоторых наворотах:
исключения в конструкторе + auto_ptr
появляются неуловимые глюки!

Думал что я неуч...
Re: BCB 6.0 - глючит даже RAII !
От: Аноним  
Дата: 06.05.08 22:27
Оценка:
Небольшая модификация:
#include <stdio.h>
class I
{
public:
virtual ~I()
{
printf("~I: %x\n", this);
}
};

class A : public I
{
public:
 A()
 {
 printf("A: %x\n", this);
 }
virtual ~A()
 {
 printf("~A: %x\n", this);
 }
};

class B : public I
{
public:
 B()
 {
 printf("B: %x\n", this);
 throw 1;
 }
virtual ~B()
 {
 printf("~B: %x\n", this);
 }
};

class C
{
I *i;
public:
C(I *src):i(src)
 {
 }
~C()
 {
 delete i;
 }
};


int main(int argc, char* argv[])
{
 try
 {
 C aa(new A);
 C bb(new B);
 }
 catch(...)
 {
 printf("caught ...\n");
 }
 return 0;
}


Тут вообще жесть полная:

A: 85429c
B: 854440
~I: 854440
~I: 854440
caught ...

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

Если убрать thow — все зашибись

A: 85429c
B: 854440
~B: 854440
~I: 854440
~A: 85429c
~I: 85429c


Если throw поставить внутри try..catch тоже все хорошо:

A: 85429c
B: 854440
~B: 854440
~I: 854440
~A: 85429c
~I: 85429c
caught ...

Re[2]: BCB 6.0 - глючит даже RAII !
От: Аноним  
Дата: 06.05.08 23:37
Оценка:
И на закуску из моей коллекции (когдато довелось с BCB работать):
Следующий код:
AnsiString s = "abcdefg";
for(;;)
 {
 AnsiString ss = GetTickCount() ? s + "123": s + "456";
 }

Вызывает бесконечный отжор памяти.
Re[3]: BCB 6.0 - глючит даже RAII !
От: Аноним  
Дата: 07.05.08 00:01
Оценка:
Такой вот тоже отжирает:
std::string s = "abcdefg";
for(;;)
 {
 std::string ss = GetTickCount() ? s + std::string("123"): s + std::string("456");
 }


А вот такой работает нормально:
std::string s = "abcdefg";
for(;;)
 {
 std::string ss = GetTickCount() ? s + "123": s + "456";
 }



А если заменить тернарный оператор на аналогичный if .. else ... то все OK во всех случаях
Re[12]: BCB 6.0 - глючит даже RAII !
От: srggal Украина  
Дата: 07.05.08 07:10
Оценка:
Здравствуйте, Аноним, Вы писали:

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


S>>>>
S>>>>        Outer outer;
S>>>>        Inner* pinner = new Inner();
S>>>>

S>>Что изменится?
А>в лучшую сторону т.е. так работает как надо.

S>>Может пора уже вам выложить сгенеренный asm?

А>легко:
А>
А>...
А>

Если честно, — не осилил, ибо по приведенному отрывку не смог ничего понять, сорри.
Re[4]: BCB 6.0 - глючит даже RAII !
От: s.ts  
Дата: 07.05.08 13:03
Оценка:
еще в догонку
void p1(const WideString& s)
{
  cout << s[1];
}

void p1(WideString& s)
{
  cout << s[1];
}

В 1-м случае индексация от нуля, во втором — от 1.
Дело, помнится, в наличии operator BSTR(), т.е. implicit преобразования к указателю, и не константном operator[], который 1-based.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.