goto и RAII в C++

Возможный дубликат:
Перейти к вне блока: вызываются ли деструкторы?

Я знаю, что оператор goto как в C, так и в C++ бесполезен почти во всех ситуациях, но я хочу знать ответ на этот вопрос только из интереса, практического смысла он не имеет.

Гарантирует ли стандарт С++, что в таких ситуациях деструкторы объектов должны вызываться правильно?

#include <iostream>

class Foo
{
public:
   Foo() { std::cout << "Foo::Foo() \n"; }
   ~Foo() { std::cout << "Foo::~Foo() \n"; }
};

int main()
{
   {
      std::size_t i = 0;
      _1:
      Foo instance;
      if (!++i)
      {
         goto _1;
      }
   }

   {
      Foo instance;
      goto _2;
   }

   _2:
   ;
}

http://liveworkspace.org/code/06031e6699c8fddda94b8594ccab1387

А как насчет других странных ситуаций с goto и C++ RAII?

Было бы здорово, если бы вы разместили здесь цитаты из стандарта C++.


person FrozenHeart    schedule 27.08.2012    source источник
comment
goto кстати не оператор.   -  person chris    schedule 28.08.2012
comment
В C goto не бесполезен, а необходим.   -  person Kerrek SB    schedule 28.08.2012
comment
Вот еще один очень информативный q/a: Будет ли использоваться goto переменные утечки?   -  person Benjamin Lindley    schedule 28.08.2012


Ответы (1)


да. Автоматические объекты гарантированно уничтожаются, когда они выходят за пределы области действия. Тот факт, что область была закрыта с помощью goto, не влияет на это правило.

Единственная ситуация, о которой я могу думать, когда это не выполняется, - это выход из области действия с помощью std::longjmp (в этом случае поведение не определено, если есть какие-либо объекты с деструкторами).

n3376

6.6 Статусы прыжков: [stmt.jump]

Пункт 2

При выходе из области видимости (независимо от того, как это было выполнено) объекты с автоматическим сроком хранения (3.7.3), созданные в этой области, уничтожаются в порядке, обратном их построению. [Примечание: для временных см. 12.2. —конец примечания] Перенос из цикла, из блока или обратно после инициализированной переменной с автоматическим сроком хранения включает уничтожение объектов с автоматическим сроком хранения, которые находятся в области действия в точке, переданной из но не в точке, куда перенесено. (См. 6.7 для передачи в блоки). [Примечание. Тем не менее, программу можно завершить (например, вызвав std::exit() или std::abort() (18.5) без уничтожения объектов класса с автоматическим временем хранения. — примечание в конце]

person Mankarse    schedule 27.08.2012
comment
Существуют способы предотвращения разрушения автоматических объектов. Например, setjmp()/longjmp() или abort(). - person Dirk Holsopple; 28.08.2012