информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Страшный баг в WindowsАтака на Internet
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Три миллиона электронных замков... 
 Doom на газонокосилках 
 Умер Никлаус Вирт 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
С таким способом объявления инстанса объекта Lock(&m_lock);... 02.03.10 19:41  Число просмотров: 2954
Автор: Killer{R} <Dmitry> Статус: Elderman
<"чистая" ссылка>
С таким способом объявления инстанса объекта Lock(&m_lock); - нигде не правильно, ибо конструктор и деструктор будут вызваны на одной и той же строчке кода.
Если бы там было Lock guard(&m_lock);
то я бы проголосовал внутрь try ибо малоли, вдруг Lock() тоже кидает исключения
Если же Lock это всетаки вызов функции а не объект, и там гдето подразумевается далее Unlock, то я голосую за в самом начале функции.
<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 вызовется после обработчика исключения, во втором варианте - до. Хотя это зависит от поведения обработчика исключения, общается ли он с ресурсом, ради которого проводилась блокировка. Если нет, то по-моему без разницы.
1




Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2024 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach