5.5.3. Оператор goto

Операторgoto обеспечивает безусловный переход к другому оператору в той же функции.

Не нужно использовать операторы goto. Они затрудняют и понимание, и изменение программ.

Оператор goto имеет следующий синтаксис:

goto метка;

Метка (label) — это идентификатор, которым помечен оператор. Помеченный оператор (labeled statement) — это любой оператор, которому предшествует идентификатор, сопровождаемый двоеточием.

end: return; // помеченный оператор; может быть целью оператора goto

Метки независимы от имен, используемых для переменных и других идентификаторов. Следовательно, у метки может быть тот же идентификатор, что и у другой сущности в программе, не вступая в конфликт с другим одноименным идентификатором. Оператор goto и помеченный оператор, на который он передает управление, должны находиться в той же функции.

Подобно оператору switch, оператор goto не может передать управление из точки, где инициализированная переменная вышла из области видимости, в точку, где эта переменная находится в области видимости.

// ...

goto end;

int ix = 10; // ошибка: goto обходит определение инициализированной

             // переменной

end:

// ошибка: код здесь мог бы использовать ix,

// но goto обошел ее объявление

ix = 42;

Переход назад за уже выполненное определение вполне допустим. Переходя назад к точке перед определением переменная приведет к ее удалению и повторному созданию.

// переход назад через определение

// инициализированной переменной приемлем

begin:

int sz = get_size();

if (sz <= 0) {

 goto begin;

}

При выполнении оператора goto переменная sz удаляется, а затем она определяется и инициализируется снова, когда управление передается назад за ее определение после перехода к метке begin.

Упражнения раздела 5.5.3

Упражнение 5.22. Последний пример этого раздела, с переходом назад к метке begin, может быть написан лучше с использованием цикла. Перепишите код так, чтобы устранить оператор goto.