Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Можно ли так делать в Си или это моветон?
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
Димон Безпарольный
В ассемблере так часто делал. Стек разгружал. А в Си так можно?

Если нужно конкретно платформа - Keil5, контроллер STM32.
gosha-z
Формально - нет. Да и неправильно это, как компилятор отследит разный calling convention, да еще и с varargs
novikovfb
Для этого есть функции setjmp и longjmp, но запутать таким образом программу и заложить трудновыявляемые глюки элементарно.
megajohn
Цитата(Димон Безпарольный @ Nov 16 2017, 10:30) *
В ассемблере так часто делал. Стек разгружал


ой, "два CALL и один RET" или даже "два CALL и один JMP" стек не то что разгрузят, но "испортят" хоть в C хоть в ASM (не вернут в прежнее состояние, будет некий StackLeak который при таких N-вызовах порушит всё )
вы уверены в своих ранее написанных программах ? Или может я что-то не понимаю
AlexRayne
Да, это моветон.
Такое применяется только там где уже нечего беречь - выбрасывание исключений.
Димон Безпарольный
Цитата(megajohn @ Nov 16 2017, 10:54) *
ой, "два CALL и один RET" или даже "два CALL и один JMP" стек не то что разгрузят, но "испортят" хоть в C хоть в ASM (не вернут в прежнее состояние, будет некий StackLeak который при таких N-вызовах порушит всё )
вы уверены в своих ранее написанных программах ? Или может я что-то не понимаю

pop sp, Dec sp и jmp. Да, 15 лет до сих пор пашет.

Цитата(AlexRayne @ Nov 16 2017, 11:19) *
Да, это моветон.
Такое применяется только там где уже нечего беречь - выбрасывание исключений.

Попробовал setjmp и longjmp. Работает. Но раз моветон, применять не буду. Самому не понравилось такое решение.
gosha-z
Цитата(Димон Безпарольный @ Nov 16 2017, 11:24) *
pop sp, Dec sp и jmp. Да, 15 лет до сих пор пашет.

И вы гарантируете одинаковость имплементации такой конструкции на всех процессорах? Что первично, inc/dec или mov?
novikovfb
Цитата(Димон Безпарольный @ Nov 16 2017, 12:30) *
Попробовал setjmp и longjmp. Работает. Но раз моветон, применять не буду. Самому не понравилось такое решение.

Эти функции использовались в С до появления в С++ исключений. Применять их стоит только в реально крайних случаях, когда нужно вернуться в указанную точку. Введение кучи флагов и их анализа для выполнения того же самого вряд ли сделает программу лучше.
Димон Безпарольный
Цитата(gosha-z @ Nov 16 2017, 11:30) *
И вы гарантируете одинаковость имплементации такой конструкции на всех процессорах? Что первично, inc/dec или mov?

Конечно нет. Я для 8051 писал. Мне на "все" и не надо было.
k155la3
Цитата(Димон Безпарольный @ Nov 16 2017, 11:30) *
. . .
Попробовал setjmp и longjmp. Работает. Но раз моветон, применять не буду. Самому не понравилось такое решение.

Если "нельзя", моветон, но "оченьнадо". Оченьнадо - это авария по питанию.
Есть в моем проете один longjmp. Обеспечивает "выпрыгивание" из вектора прерывания в блок,
находящийся в начале main().
jcxz
Цитата(novikovfb @ Nov 16 2017, 10:34) *
Эти функции использовались в С до появления в С++ исключений. Применять их стоит только в реально крайних случаях, когда нужно вернуться в указанную точку. Введение кучи флагов и их анализа для выполнения того же самого вряд ли сделает программу лучше.

Да ладно. "Моветон" и т.п. - что за пуританство? Если это улучшает читаемость кода и стройность алгоритма, то применять можно и нужно.
Сам так иногда делаю. Когда нужно вернуться в предопределённое положение (функцию) из дерева вложенных вызовов из множества мест. Реализовывать такое на специальных возвращаемых значениях (в каждой функции, из которой может быть такой возврат!) - это будет куча лишнего кода.
Куда элегантнее и прозрачнее будет восстановить стековый фрейм.
А насчёт "на всех процессорах": а это реально так нужно? А ничего если в используемой ОС тоже есть ассемблерные вставки и перенос её на другое ядро производится написанием порта под нужное ядро? Кто же мешает так сделать и в этом случае? Тем более что кода тут - с гулькин нос.

В конце концов: си (или ++) - это инструмент, а не самоцель. А цель всё-таки - это наиболее эффективное решение задачи (написание эффективного ПО).

PS: си-шными setjmp/longjmp я не пользуюсь. Пишу свои асм-функции сохранялки/переключалки стекового фрейма.
Hitest
Это даже у системных программеров под Винду (конкретно мы, группа, реализовывали свой драйвер COM порта, ...15 лет назад) было моветоном.
Можно писать как угодно коряво, но лучше красиво. В грамотных ассемблерных вставочках комментарий в каждой строке. Код должен своим видом показывать, что он правилен. Как-то так ИМХО.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.