Есть много споров о goto
Команда, этот вопрос не о правильности или неправильности его использования, а более просто вопрос о том, создает ли он когда-либо другую сборку.
Я специально смотрю на Visual Studio 2013, но пример в любом компиляторе был бы замечательным.
Область действия метки — это функция, в которой она находится (§6.3.4). Это подразумевает, что вы можете использовать
goto
прыгать в и из блоков. Единственным ограничением является то, что вы не можете перепрыгнуть через инициализатор или обработчик исключений (§13.5).
Один из немногих разумных примененийgoto
в обычном коде вырваться из вложенного цикла илиswitch
-заявление.
Тогда мой вопрос: есть ли экземпляр, в котором goto
все еще производит сборку, отличную от той, что уже может быть достигнута с использованием других структур управления?
Например, это производит идентичную сборку:
auto r = rand();
auto a = 0;
for(auto i = rand(); i > 0; --i){
switch(r){
case 1:
++sum;
goto END;
case default:
sum += rand();
break;
}
}
sum++;
END:
Для этого неgoto
код:
auto r = rand();
auto b = false;
auto a = 0;
for(auto i = rand(); i > 0; --i){
switch(r){
case 1:
++sum;
b = true;
break;
case default:
sum += rand();
break;
}
if(b)break;
}
if(!b)sum++;
Вот мой опыт: у меня когда-то было немного кода, который был очень время критично. И у него был цикл, который повторялся в среднем ноль раз (while (условие) …) и условие почти всегда было ложным. Компилятор настаивал на оптимизации цикла, перемещая вещи за пределы цикла — даже когда цикл вообще не выполнялся, поэтому замедлял его.
Я попытался переписать цикл с помощью goto, надеясь запутать оптимизатор настолько, чтобы отказаться от оптимизации кода, и потерпел неудачу. gcc и clang оптимизируют в зависимости от фактического потока управления, независимо от того, какой код C или C ++ вы используете.