2016-06-20 2 views
0

В следующем C-коде f звонки g и g звонки h. Обратите внимание, что goto в h, однако: он вернется к f, если a удовлетворяет определенному условию.Состояние стека после goto

void h(int a) 
{ 
    if (a > 10) 
     goto out; 
} 

void g(int a, int b) 
{ 
    h(a); 
} 

void f(int a, int b) 
{ 
    g(a, b); 
    return; 
out: 
    printf("b: %d\n", b); 
} 

Мой вопрос: как стопка будет, если goto срабатывает? Будут ли оставлены g и h? И будет f еще напечатать правильное значение b? (или он будет печатать его правильно только в некоторых случаях, когда мне повезет?)

(Пожалуйста, я не хочу обсуждать, является ли это хорошей практикой или если это вообще нужно использовать. что фактический код достаточно сложный, так что компилятор не будет достаточно умен, чтобы, например, оптимизировать g)

[Я могу дать подробную информацию о том, почему я это делаю, если это имеет значение - я не знаю думаю, что делает]

+3

Этикетки AFAIK должны быть локализованы для функциональной области. Вы не можете сделать это в стандарте C. – LPs

+0

Ваш код не скомпилирован для меня, например, состояния комментариев к файлам LP, gotos являются локали для функций областей –

+2

Возможный дубликат [Как «перейти» в другую функцию в c?] (Http : //stackoverflow.com/questions/21355110/how-to-goto-into-different-function-in-c) – LPs

ответ

4

Это приведет к непредсказуемому поведению в стандартном C.

От 6.8.6.1/1 в C Language Standard:

Идентификатор в Гото заявлении нарекут метку, расположенную где-то в прилагаемой функции. Оператор goto не должен прыгать вне пределов области идентификатора, имеющего измененный тип , внутри области этого идентификатора.

4

Вопрос недействителен, потому что это просто невозможно сделать следующим образом: вы можете только goto в функции, а не между функциями.

Для перехода между функциями вы можете использовать setjmp/longjmp.

+0

Также нет необходимости в стеке на языке C из языкового стандарта. – Olaf

+0

.. где забавная вещь 'setjmp' /' longjmp' заключается в том, что их разработчик хорошо знал о потенциальных проблемах стека (в реализациях, которые его используют), поэтому они были разработаны для того, чтобы * not * использовать тот же стек, что и обычные функции. (См. Много-много вопросов о переполнении стека, например [этот] (http://stackoverflow.com/q/7969075/2564301).) – usr2564301

1

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

Этикетки являются локальными для одной функции, вы не можете перепрыгивать между различными функциями.

ПРИМЕЧАНИЕ. - По-моему, использование инструкции goto сильно обескуражено.

исх: http://www.tutorialspoint.com/cprogramming/c_goto_statement.htm

+3

«Использование инструкции goto сильно обескуражено» является субъективным. Я согласен с этим только на «общий» случай. Бывают случаи, когда использование 'goto' является самым простым способом, например. г. обработка ошибок. – glglgl

+0

Я согласен @glglgl. Ядро Linux полно примеров, где оно подходит –

+0

'goto' имеет свои приложения ** в C **. Так что нет, это не обескураживает. Это то, что говорит профессор CS. Профессор с некоторым пониманием практического программирования позже ослабит это утверждение. – Olaf

-1

Вы не можете сделать это, поскольку метки являются локальными для каждой конкретной функции. Однако ближайшим стандартным эквивалентом является пара функций setjmp() и longjmp(). Это должно сработать. :)

+1

setjmp() и longjmp() не совсем эквиваленты IMHO .. – sjsam

+0

Согласен, но для потребностей новичка его должно хватить. :) –

Смежные вопросы