| 
 
 
 
 Легенда:
  новое сообщение 
  закрытая нитка 
  новое сообщение 
  в закрытой нитке 
  старое сообщение   | 
Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
Новичкам также крайне полезно ознакомиться с данным документом.
| [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 вызовется после обработчика исключения, во втором варианте - до. Хотя это зависит от поведения обработчика исключения, общается ли он с ресурсом, ради которого проводилась блокировка. Если нет, то по-моему без разницы. |  
 
 
 |  |