Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
| | | | | |
да нет, это в дебаге было 02.03.10 21:49 Число просмотров: 3101
Автор: dl <Dmitry Leonov> Отредактировано 02.03.10 21:50 Количество правок: 1
|
Да и в релизе оптимизатор скорее бы выкинул какой-нибудь код, а не продлил жизнь объекта. Буду считать глюком, может быть даже своим :)
|
<programming>
|
[C++] execptions - stack unwinding & calling destructions 02.03.10 17:51
Автор: void <Grebnev Valery> Статус: Elderman Отредактировано 02.03.10 21:05 Количество правок: 1
|
Which way of placement of the Lock() object is more safe (preferable) for the modern MS compilers and in a general case?
void func(void)
{
Lock lock(&m_lock);
try
{
}
catch(std::exception& e )
{
....
}
catch(...)
{
....
}
}
OR
void func(void)
{
try
{
Lock lock(&m_lock);
}
catch(std::exception& e )
{
....
}
catch(...)
{
....
}
}
---
Thank you
|
|
С таким способом объявления инстанса объекта Lock(&m_lock);... 02.03.10 19:41
Автор: Killer{R} <Dmitry> Статус: Elderman
|
С таким способом объявления инстанса объекта Lock(&m_lock); - нигде не правильно, ибо конструктор и деструктор будут вызваны на одной и той же строчке кода.
Если бы там было Lock guard(&m_lock);
то я бы проголосовал внутрь try ибо малоли, вдруг Lock() тоже кидает исключения
Если же Lock это всетаки вызов функции а не объект, и там гдето подразумевается далее Unlock, то я голосую за в самом начале функции.
|
| |
[C++] good point 02.03.10 21:07
Автор: void <Grebnev Valery> Статус: Elderman Отредактировано 02.03.10 21:10 Количество правок: 1
|
I mean...
>>то я бы проголосовал внутрь try ибо малоли, вдруг Lock() тоже кидает исключения
|
| |
анонимные автоматические объекты вполне себе живут до конца блока 02.03.10 20:03
Автор: dl <Dmitry Leonov>
|
Я даже не поленился и проверил на тестовом классе, деструкторы отрабатывают именно так, как я написал.
|
| | |
VS 2008: 02.03.10 20:24
Автор: Killer{R} <Dmitry> Статус: Elderman
|
VS 2008:
class CC
{
public:
CC()
{
printf("CC\n");
}
~CC()
{
printf("~CC\n");
}
};
int wmain(int argc, wchar_t* argv[])
{
CC();
printf("locked\n");
return 0;
}
---
output:
CC
~CC
locked
---
потому что 12.2.3
(см) http://www.kuzbass.ru/docs/isocpp/special.html#class.temporary
изменение кода Main на
int wmain(int argc, wchar_t* argv[])
{
const CC &cc = CC();
printf("locked\n");
return 0;
---
ведет к такому:
CC
locked
~CC
---
потому что 12.2.5 и вот : http://alenacpp.blogspot.com/2008/01/const.html
|
| | | |
мистика какая-то 02.03.10 21:27
Автор: dl <Dmitry Leonov> Отредактировано 02.03.10 21:40 Количество правок: 2
|
Я тоже сначала засомневался насчет временного объекта, но решил себя проверить и быстро воткнул код в проект, что был под рукой. Сработало так, как будто объект был не временным, я даже порадовался и решил запомнить на будущее. Сейчас попробовал воспроизвести, не получилось ни там, ни на чистом проекте. Может быть, это такие шутки minimal rebuild.
Но в случае нормального объекта все-таки лучше смотреть на обработчик. Поскольку
struct A
{
int m_i;
A(int i):m_i(i)
{
cout << "A::A " << m_i << endl;
}
~A()
{
cout << "A::~A " << m_i << endl;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
A a(1);
try
{
A a(2);
throw 0;
}
catch (...)
{
cout << "catch" << endl;
}
return 0;
}
---
выдаст
A::A 1
A::A 2
A::~A 2
catch
A::~A 1
---
И если класс Lock из первого поста предназначался для защиты от совместного использования некого ресурса, к которому вдруг есть обращение в обработчике исключения, первый вариант окажется надежнее.
|
| | | | |
[C++] мистика какая-то 02.03.10 21:41
Автор: void <Grebnev Valery> Статус: Elderman
|
> Я тоже сначала засомневался насчет временного объекта, но > решил себя проверить и быстро воткнул код в проект, что был > под рукой. Сработало так, как будто объект был не > временным, я даже порадовался и решил запомнить на будущее. > Сейчас попробовал воспроизвести, не получилось ни там, ни > на чистом проекте. Может быть, это такие шутки minimal > rebuild.
If the result of the code is not used somewhere further, the Microsoft compiler will strip the code (you will not find that code in *.asm), for example, the code below will not result in an exception in the release (optimized) version:
void f()
{
A a;
int b = 0;
int c = 1/b;
}
But the same code will give you an exception, if you force the compiler to leave the code { int b = 0; int c = 1/b;}
For example,
void f()
{
A a;
int b = 0;
int c = 1/b;
printf("%d", c);
}
Will it help?
|
| | | | | |
Эксцепшны тут не причем. Проблема поставленного вопроса в... 02.03.10 21:50
Автор: Killer{R} <Dmitry> Статус: Elderman
|
Эксцепшны тут не причем. Проблема поставленного вопроса в том что инстанс объекта созданного кострукций Lock() не доживет даже до try.
|
| | | | | | |
I corrected the example I posted - Lock lock(&m_cs) 02.03.10 22:03
Автор: void <Grebnev Valery> Статус: Elderman
|
|
| | | | | | | |
в таком случае - внутрь try..except в том случае если код... 02.03.10 22:21
Автор: Killer{R} <Dmitry> Статус: Elderman
|
в таком случае - внутрь try..except в том случае если код внутри catch не требует занятого cs
потому что конструктор Lock тоже теоретически может кинуть исключение
|
| | | | | | | | |
But... If an exception occurs in the Lock ctor(), the object... 02.03.10 23:23
Автор: void <Grebnev Valery> Статус: Elderman
|
> в таком случае - внутрь try..except в том случае если код > внутри catch не требует занятого cs > потому что конструктор Lock тоже теоретически может кинуть > исключение
But... If an exception occurs in the Lock ctor(), the object will be partially created. Will unwinding work for the partially created objects? I mean...if an exception occurs in the Lock ctor(), dtor() (and guard unlock) will not be called. Right?
|
| | | | | | | | | |
Исключения в конструкторе - нормальная ситуация и все будет... 03.03.10 00:50
Автор: Killer{R} <Dmitry> Статус: Elderman
|
Исключения в конструкторе - нормальная ситуация и все будет хорошо.
Деструктор же напротив - исключения кидать не должен - все будет плохо.
|
| | | | | | | | | | |
не все - деструктор для неполностью сконструированного объекта действительно не будет вызван 03.03.10 00:58
Автор: dl <Dmitry Leonov> Отредактировано 03.03.10 01:05 Количество правок: 1
|
И если он выполнял какую-то нетривиальную работу, которую нельзя свести к деструкторам успевших сконструироваться полей объекта, действительно случится проблема.
И похоже, что решение этой проблемы более разумно отнести на более высокий уровень, чем функция, блокировкой которой занимается этот объект - что добавляет еще один плюс в копилку первого варианта :)
|
| | | | | | | | | | | |
ну дык 03.03.10 01:35
Автор: Killer{R} <Dmitry> Статус: Elderman
|
Конструктор сам должен быть exception-safe и учитывать возможность бросания исключения в нем самом и освобождать автоматически не освобожаемые ресурсы.
Впрочем у меня давно утвердилась привычка использовать всяческие автохэндлы и прочие scope-guard-like холдеры ресурсов которые устраняют такую проблему как таковую.
|
| | | | | | | | | | | | |
это ж как матрешка 03.03.10 10:39
Автор: dl <Dmitry Leonov>
|
> Впрочем у меня давно утвердилась привычка использовать > всяческие автохэндлы и прочие scope-guard-like холдеры > ресурсов которые устраняют такую проблему как таковую.
Только отодвигают - ведь точно так же, как и в случае с этим Lock, теоретически можно допустить возникновение исключения в конструкторах уже этих холдеров. Или в какой-то момент все-таки остановиться и решить - вот в этом простейшем конструкторе исключений точно не будет. В принципе, это же можно отнести и к самому Lock - его функциональность, скорее всего, попадает под определение простейшего.
|
| | | | | |
да нет, это в дебаге было 02.03.10 21:49
Автор: dl <Dmitry Leonov> Отредактировано 02.03.10 21:50 Количество правок: 1
|
Да и в релизе оптимизатор скорее бы выкинул какой-нибудь код, а не продлил жизнь объекта. Буду считать глюком, может быть даже своим :)
|
| | | |
says nothing in question 02.03.10 21:11
Автор: void <Grebnev Valery> Статус: Elderman
|
|
|
в общем случае я голосую за первый вариант 02.03.10 18:21
Автор: dl <Dmitry Leonov>
|
Первый вариант выглядит надежнее, поскольку тут ~Lock вызовется после обработчика исключения, во втором варианте - до. Хотя это зависит от поведения обработчика исключения, общается ли он с ресурсом, ради которого проводилась блокировка. Если нет, то по-моему без разницы.
|
|
|