Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> PIMPL+auto_ptr на VS2010, проблема реализации 
V
    Опции темы
mes
Дата 23.1.2011, 12:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(azesmcar @  23.1.2011,  07:28 Найти цитируемый пост)
проверил, в деструкторе к impl можно спокойно обращаться, т

ну так и должно оно быть smile


Цитата(azesmcar @  23.1.2011,  07:28 Найти цитируемый пост)
Почему в таком случае студия хочет деструктора там, где он ей не нужен?

наверно слово pre_destructor неправильно подобрал.. 
имелась ввиду такая условная схема:
Код

A::~A() 
${  
      {  ...  } // определенный пользователем деструктор
... // вызов деструкторов  дата-членов и базовых
$} 




--------------------
PM MAIL WWW   Вверх
azesmcar
Дата 23.1.2011, 12:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(mes @  23.1.2011,  12:22 Найти цитируемый пост)
наверно слово pre_destructor неправильно подобрал.. 
имелась ввиду такая условная схема:

теперь понятнее..и насколько это соответствует стандарту? smile

Добавлено через 20 секунд
Цитата(mes @  23.1.2011,  12:22 Найти цитируемый пост)
ну так и должно оно быть 

ну вообще да, так предполагается smile 
PM   Вверх
mes
Дата 23.1.2011, 13:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(azesmcar @  23.1.2011,  11:35 Найти цитируемый пост)
и насколько это соответствует стандарту? 

такая схема или место формирования деструктора ?



--------------------
PM MAIL WWW   Вверх
azesmcar
Дата 23.1.2011, 13:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(mes @  23.1.2011,  13:05 Найти цитируемый пост)
такая схема или место формирования деструктора ?

больше всего интересует итог всего этого, т.е. такое поведение данного кода.
PM   Вверх
mes
Дата 23.1.2011, 14:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



насчет схемы отсюда можно сделать вывод :
Цитата

After executing the body of the destructor and destroying any automatic objects allocated within the body, a destructor for class X calls the destructors for X’s direct members, the destructors for X’s direct base classes ...
...
A return statement (6.6.3) in a destructor might not directly return to the caller; before transferring control to the caller, the destructors for
the members and bases are called.

а когда формировать эту часть деструктора, в стандарте вроде не сказано .. 



--------------------
PM MAIL WWW   Вверх
azesmcar
Дата 24.1.2011, 06:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(mes @  23.1.2011,  14:10 Найти цитируемый пост)
A return statement (6.6.3) in a destructor might not directly return to the caller; before transferring control to the caller, the destructors for
the members and bases are called.

ну это естественно.

Цитата(mes @  23.1.2011,  14:10 Найти цитируемый пост)
After executing the body of the destructor and destroying any automatic objects allocated within the body, a destructor for class X calls the destructors for X’s direct members, the destructors for X’s direct base classes ...

smile 
т.е. именно деструктор должен вызывать, деструкторы для базового классов и членов.

Цитата(mes @  23.1.2011,  12:22 Найти цитируемый пост)
// вызов деструкторов  дата-членов и базовых

тогда это не соответствует стандарту (если это конечно работает именно так)
PM   Вверх
xvr
Дата 24.1.2011, 14:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(azesmcar @  23.1.2011,  08:28 Найти цитируемый пост)
проверил, в деструкторе к impl можно спокойно обращаться, т.е. удаляется объект после выхода из тела деструктора в файле реализации. Почему в таком случае студия хочет деструктора там, где он ей не нужен?
Возможно он ей нужен, что бы сгенерить код поддержки исключений, для раскрутки стека в возможном исключении после вызова конструктора std::auto_ptr<XImpl> (хотя его там и нет smile )
Т.е. то, что она (студия) сгенерила деструктор auto_ptr в конструкторе X::X(), еще не значит, что она его когда либо вообще позовет  smile 



Это сообщение отредактировал(а) xvr - 24.1.2011, 14:58
PM MAIL   Вверх
mes
Дата 24.1.2011, 23:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(azesmcar @  24.1.2011,  05:08 Найти цитируемый пост)
тогда это не соответствует стандарту (если это конечно работает именно так) 

не понял о чем речь..

Добавлено через 1 минуту и 49 секунд
Цитата(xvr @  24.1.2011,  13:57 Найти цитируемый пост)
Возможно он ей нужен, что бы сгенерить код поддержки исключений,

да, хороший повод для формирования деструктора..


--------------------
PM MAIL WWW   Вверх
azesmcar
Дата 25.1.2011, 06:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(mes @  24.1.2011,  23:37 Найти цитируемый пост)
не понял о чем речь..

Вы описали поведение деструктора вот так

Цитата(mes @  23.1.2011,  12:22 Найти цитируемый пост)
A::~A() 
${  
      {  ...  } // определенный пользователем деструктор
... // вызов деструкторов  дата-членов и базовых
$} 

т.е. он формирует пре-деструктор (назовем его так) там, где определен конструктор. По стандарту
Цитата

a destructor for class X calls the destructors for X’s direct members

т.е. именно деструктор класса X должен вызывать деструкторы своих непосредственных членов, а не пре-деструктор.

Цитата(xvr @  24.1.2011,  14:57 Найти цитируемый пост)
Возможно он ей нужен, что бы сгенерить код поддержки исключений, для раскрутки стека в возможном исключении после вызова конструктора std::auto_ptr<XImpl> (хотя его там и нет  )
Т.е. то, что она (студия) сгенерила деструктор auto_ptr в конструкторе X::X(), еще не значит, что она его когда либо вообще позовет   

ну gcc ведь как-то работает, т.е. задача по сути решаемая. smile 
PM   Вверх
mes
Дата 25.1.2011, 09:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 144
Всего: 250



Цитата(azesmcar @  25.1.2011,  05:11 Найти цитируемый пост)
т.е. он формирует пре-деструктор (назовем его так) там, где определен конструктор. По стандарту

если по стандарту, то он называется destructor, а то , что определяет пользователь destructor`s body..

Цитата(azesmcar @  25.1.2011,  05:11 Найти цитируемый пост)
т.е. именно деструктор класса X должен вызывать деструкторы своих непосредственных членов, а не пре-деструктор.

ну так разноглассие ввиду неправильно подобранных названий, предыдущий абзац "решает" эту проблему  smile 

ну а если еще и соответствовать пункту о return, то условно 
Код

A::A ()          __DTOR(A, 
{
    //  user defined
} 
)
//  при
#define __DTOR(cls,user_code) 
{
    struct l {
         static body    (cls this)  user_code
         static destroy (cls this) { ... }
    }
    l::body ();
    l::destroy();
}






--------------------
PM MAIL WWW   Вверх
xvr
Дата 25.1.2011, 11:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(azesmcar @  25.1.2011,  06:11 Найти цитируемый пост)
ну gcc ведь как-то работает, т.е. задача по сути решаемая.

Сильно зависит от контекста. Например тут:
Код

class X {
 std::auto_ptr<Y> some;
 SomeClass obj_with_nontrivial_constructor;
public:
 X(Y* y) :some(y) {}
};
деструктор для Y реально понадобится, т.к. порядок конструирования членов - some а затем obj_with_nontrivial_constructor, и в случае исключения в конструкторе obj_with_nontrivial_constructor придется звать деструктор для Y.
А тут:
Код

class X {
 SomeClass obj_with_nontrivial_constructor;
 std::auto_ptr<Y> some;
public:
 X(Y* y) :some(y) {}
};
деструктор для Y не нужен, т.к. порядок конструирования членов обратный, и после конструктора auto_ptr исключение возникнуть не может (т.к. просто негде).  smile 

VS скорее всего не вдается в такие тонкости и просто лепит инстанс деструктора безусловно  smile 

PM MAIL   Вверх
azesmcar
Дата 25.1.2011, 12:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(xvr @  25.1.2011,  11:35 Найти цитируемый пост)
Сильно зависит от контекста. Например тут:

в gcc нет никаких волнений по этому поводу, все деструкторы нормально вызываются.

Цитата(xvr @  25.1.2011,  11:35 Найти цитируемый пост)
деструктор для Y реально понадобится, т.к. порядок конструирования членов - some а затем obj_with_nontrivial_constructor, и в случае исключения в конструкторе obj_with_nontrivial_constructor придется звать деструктор для Y.

в моем примере там вообще ничего нету кроме auto_ptr<XImpl>. На эту тонкость студии тоже по всей видимости плевать smile 

Цитата(xvr @  25.1.2011,  11:35 Найти цитируемый пост)
VS скорее всего не вдается в такие тонкости и просто лепит инстанс деструктора безусловно   

Да, так и есть. smile 

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

Это сообщение отредактировал(а) azesmcar - 25.1.2011, 12:05
PM   Вверх
xvr
Дата 25.1.2011, 12:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(azesmcar @  25.1.2011,  12:02 Найти цитируемый пост)
в gcc нет никаких волнений по этому поводу, все деструкторы нормально вызываются.
Увы, не нормально. Сделал тестовый пример:
Код

#include <memory>

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

class Y;

class X {
 std::auto_ptr<Y> some;
 SomeClass obj_with_nontrivial_constructor;
public:
 X(Y* y) :some(y) {}
};

void q(Y* y)
{
 new X(y);
}
gcc 4.5.1. Деструктор для std::auto_ptr<Y> был сгенерен, но деструктора для Y в нем не позвали :(

Код

std::auto_ptr<Y>::~auto_ptr():
    .cfi_startproc
    pushq    %rbp
    .cfi_def_cfa_offset 16
    movq    %rsp, %rbp
    .cfi_offset 6, -16
    .cfi_def_cfa_register 6
    subq    $16, %rsp
    movq    %rdi, -8(%rbp)
    movq    -8(%rbp), %rax
    movq    (%rax), %rax
    movq    %rax, %rdi
    call    operator delete(void*)
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc


А вот если добавить описание класса Y (с деструктором), то его позовут -
Код

std::auto_ptr<Y>::~auto_ptr():
    .cfi_startproc
    pushq    %rbp
    .cfi_def_cfa_offset 16
    movq    %rsp, %rbp
    .cfi_offset 6, -16
    .cfi_def_cfa_register 6
    pushq    %rbx
    subq    $24, %rsp
    movq    %rdi, -24(%rbp)
    movq    -24(%rbp), %rax
    movq    (%rax), %rbx
    .cfi_offset 3, -24
    testq    %rbx, %rbx
    je    .L10
    movq    %rbx, %rdi
    call    Y::~Y()
    movq    %rbx, %rdi
    call    operator delete(void*)
.L10:
    addq    $24, %rsp
    popq    %rbx
    leave
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
Так что это явно баг в gcc  smile 

PM MAIL   Вверх
azesmcar
Дата 25.1.2011, 12:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



xvr

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

Добавлено через 7 минут и 21 секунду
выкладываю свой пример

x.h
Код

#ifndef x_h_included
#define x_h_included

#include <memory>
#include <map>

class XImpl;
class X
{
    std::map<int, int> obj_with_nontrivial_constructor;
    std::auto_ptr<XImpl> impl;
private:
    void create_ximpl();
public:
    X()
    {
        this->create_ximpl();
    };
    ~X();
};

#endif // x_h_included


ximpl.h
Код

#ifndef ximpl_h_included
#define ximpl_h_included

#include <iostream>

class XImpl
{
public:
    XImpl();
    ~XImpl();
};
#endif // ximpl_h_included

x.cpp
Код

#include <iostream>
#include "ximpl.h"
#include "x.h"

void X::create_ximpl()
{
    impl.reset(new XImpl());
}

X::~X()
{
    std::cout << "X::~X()" << std::endl;
}

int main()
{
    X x;
}

ximpl.cpp
Код

#include <iostream>
#include "ximpl.h"

XImpl::XImpl()
{
    std::cout << "XImpl::XImpl()" << std::endl;
}
XImpl::~XImpl()
{
    std::cout << "XImpl::~XImpl()" << std::endl;
};


выводит
Цитата

X::~X()
XImpl::~XImpl()

на gcc version 4.5.1
PM   Вверх
xvr
Дата 25.1.2011, 12:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

Репутация: 60
Всего: 223



Цитата(azesmcar @  25.1.2011,  12:39 Найти цитируемый пост)
Не совсем понял..можно выложить полный исходники тестового примера?

В примере деструктор Y не вызывается (вне зависимости от исключений и от чего то бы ни было  smile  )
Если раскоментарить тело класса Y в файле 1.cpp, то деструктор вызывается


Присоединённый файл ( Кол-во скачиваний: 4 )
Присоединённый файл  bug.zip 0,73 Kb
PM MAIL   Вверх
Страницы: (3) Все 1 [2] 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0663 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.