В ассемблере как захочешь, так и будет. Там у вас полная свобода действий. Никто никого не контролирует. Вся ответственность за последствия выполнения программы лежит на програмисте. Компилятор только вычисляет адреса и переводит инструкции в шеснадцатиричную кодировку. По поводу Соглашусь частично. Если свободных РОН дофига то скорее всего они для локальных переменных и используются. Ну а когда средства ограничены, то по моему мнению, используется приём как и в обработчиках прерываний. При входе в ПП значения всех используемых РОН сохраняются в стек. Перед выходом из ПП эти значения из стека востанавливаются. Так, что стек задействован, но не для хранения локальных переменных. По поводу вашего кода Код (C++): int func_A(int a, int b) { if (a< 10) { int c = 0; c = b-a; if (c >20) goto label_1; } return (a); label_1: return (b); } Ничего криминального в нём нет. Если вы не переходите по метке label_1 то выходите по оператору return (a), если переходите - выход по return (b). В обоих случаях у вас стандартный выход из функции, только разные возвращаемые значения. Так, что применение goto в данном случае ничего не портит. Теперь вернёмся к началу спора. Использует goto стек или нет? Своё видение процесса я изложил тут #53.
Не портит, но и не улучшает. Зато вот так и короче и понятнее Код (C++): int func_A(int a, int b) { if (a< 10) { int c = 0; c = b-a; if (c >20) return (b); } return (a); }
Вопрос оптимальности не стоял. SergeiL хотел продемонстрировать, что после пременения goto переменная "с" останется в стеке навсегда. Даже если предположить, что она туда попадает, а мне в это совсем не верится, то в данном коде всё будет нормально. Вот если-бы он по goto уходил из функции на совсем, это бы привело к срыву стека. Естестванно. В очередной раз убеждаюсь - выучить десятка два операторов языка програмирования, не значит стать програмистом. Надо ещё уметь правильно ими пользоваться. На это могут уйти годы. Читаю "AVR. Учебный курс." автор DI HALT. Завидую человеку белой завистью. Как красиво и элегантно человек умеет писать. Предел мечтаний.
Эта тема вечная, ибо есть две группы програмистов. Одни goto используют и считают это класным. Другие goto не используют и считают что goto это кака. Оба мнения имеют право на жизнь ибо каждый пишет так, как ему удобно.
Может быть... не смотрел - он в Debian 9 по умолчанию. Перенёс старый проект из Debian 6 на новоустановленноую систему и вот. Пришлось пилить.
Может goto и не надо... но язык разрабатывали и пилили точно не дебилы коли оно там есть. А вот "&" и "&&" заменять словом "and" что-то никто не обругал, хотя это не только не красиво, а вполне идиотизм (посмотрите в темах)
Правду говорят старожилы: "При нападении стаи волков на лошадь, если они сильно голодны, то съедают её вместе с телегой"
Никашерно! У функции должен быть только один выход! (не воспринимайте серьёзно - это я "MISRAста" включил ))
Переход внутри функции возможно и не красиво но если на пользу, то можно. Ключевое слово "Внутри функции". На вкус и цвет товарищей нет. Вот я например сижу на Си (чистом а не C++). На C++ возможно это и не красиво. А вот на ASM нормально. Ведь это наверное не материться на языке программирования. Интересно а на Паскаль это можно? Тут люди умудряются "&&" на "AND" поменять и ничего, а это всего-то "goto" чтобы вернуться на несколько шагов назад внутри цикла... и что?
Так там без JMP никуда. Ага, таки создатели компилятора подстраховались от глупых решений. То-ли дело ASM - полная свобода в совершении самых идиотских поступков.
Небольшая ремарка C и C++ -- это два разных языка. "Грязный" C, как бы он этого не хотел, ни когда не станет C++.
А то! Ну, как сказать, невеста, разумеется, непорочна, а брачная ночь - первая Пример не для каждого компилятора, но GCC - инструмент настоящих мужчин! Скомпилируйте вот это в Ардуино IDE и посмотрите, что напечатается при выполнении Код (C++): static void * shitLabel; static void shitCode(void) { goto * shitLabel; } void setup() { Serial.begin(57600); shitLabel = && fin; goto *((void *) shitCode); Serial.println("Show must go on!"); return; fin: Serial.println("Okay, Houston, we've had a problem here!"); } void loop(void) {}
Переходы по меткам и функциям конечно тот ещё способ получить головную боль, но нам нужен хардкор.... Код (C++): goto *(0x007C);