Цитата(Скопидор @ Apr 15 2009, 10:47)

Да я не собираюсь флудить, нужен или не нужен goto. Просто хотел узнать как это реализуется: осуществляется «прыжок» за пределы блока и при этом, КАК-ТО, восстанавливается контекст, сохранённый на входе в блок.
Обычно ничего никуда не сохраняется и не восстанавливается в таких блоках.
Код
voif foo()
{
int i = 0;
{
char c;
...
}
++i;
{
long l;
...
}
--i;
}
Компилятор анализирует всю функцию и в исполняемом коде уже на входе в функцию на стеке резервируется, грубо говоря
Код
struct {
int i;
union {
char c;
long l;
};
} local_variables;
и больше стек туда-сюда не дёргается, просто происходит использование места на стеке в соответствии с деревом вложенных блоков кода. При минимальной современной оптимизации ещё и происходит анализ использования переменных и если какая-то используется до середины и дальше не нужна, а какая-то другая наоброт - используется только от середины (первое использование после последнего использования той), то они тоже накладываются в стеке для экономии его размера.
При этом переход по goto ничего не ломает (если он не обходит инициализацию переменной при попадании на метку, т.е. вопросы не к точке прыжка goto, а к точке приземления), так как структура/объединение на стеке остаются неподвижными, меняется только интерпретация.
Естественно, это так просто только для типов без конструкторов/деструкторов.
Особенно учитывая то, что во вложенных вызовах могут произойти исключения, которые подействуют "аналогично goto" с точки зрения этих объектов, а при отсутствии в данной функции try/catch её вообще всё "прошьёт". Поэтому для них в стековых кадрах функций устраиваются записи о деструкторах, которые необходимо выполнить при выходе из блока и порядке этих вызовов, при выходе из любого блока по goto/return/исключению просматриваются эти записи и вызываются необходимые деструкторы для автоматических объектов в блоках (unwind).
Код
#include <iostream>
class FOO
{
public:
FOO(int i_) : i(i_) { std::cout << __PRETTY_FUNCTION__ << " (" << i << ")\n"; }
~FOO() { std::cout << __PRETTY_FUNCTION__ << " (" << i << ")\n"; }
private:
int i;
};
int main(int ac, char **av)
{
FOO f1(1);
{
FOO f2(2);
if(ac == 1)
goto aaa;
// в случае перехода даже не сконструируется, но место на стеке под поле i зарезервировано заранее
FOO f3(3);
}
aaa:;
}
Вызываем с аргументом в командной строке (goto не выполняется)
Цитата
FOO::FOO(int) (1)
FOO::FOO(int) (2)
FOO::FOO(int) (3)
FOO::~FOO() (3)
FOO::~FOO() (2)
FOO::~FOO() (1)
Вызываем без аргумента
Цитата
FOO::FOO(int) (1)
FOO::FOO(int) (2)
FOO::~FOO() (2)
FOO::~FOO() (1)
Цитата(Скопидор @ Apr 15 2009, 11:09)

А что такое «oak»?
http://www.abbyyonline.ru/Translate.aspx?l...1&words=oakМожете для своих вещей выбрать другое имя. Можете несколько, для разных частей проекта свои.
Цитата(Скопидор @ Apr 15 2009, 11:09)

Т.е. Ваше сообщение было к тому, что «сломать» очень сложно? Но ведь стандартная библиотека – это не только классы и шаблоны.
Оно к тому, что в языке есть средства для того, чтобы можно было не ломать.
Цитата(andrew_b @ Apr 15 2009, 11:19)

Так это давным-давно deprecated.
У меня просто до сих пор в ходу mingw32-gcc 3.4.2 пятилетней давности, у него в backward/ ещё болтается всё