реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Можно ли так делать в Си или это моветон?, Функция А вызывает Б которая вызывает С и из С вернуться в А минуя Б
Димон Безпарольн...
сообщение Nov 16 2017, 06:30
Сообщение #1


Знающий
****

Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247



В ассемблере так часто делал. Стек разгружал. А в Си так можно?

Если нужно конкретно платформа - Keil5, контроллер STM32.
Go to the top of the page
 
+Quote Post
gosha-z
сообщение Nov 16 2017, 06:32
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 327
Регистрация: 30-10-05
Пользователь №: 10 288



Формально - нет. Да и неправильно это, как компилятор отследит разный calling convention, да еще и с varargs
Go to the top of the page
 
+Quote Post
novikovfb
сообщение Nov 16 2017, 06:36
Сообщение #3


Знающий
****

Группа: Участник
Сообщений: 518
Регистрация: 29-09-11
Пользователь №: 67 450



Для этого есть функции setjmp и longjmp, но запутать таким образом программу и заложить трудновыявляемые глюки элементарно.
Go to the top of the page
 
+Quote Post
megajohn
сообщение Nov 16 2017, 07:54
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 080
Регистрация: 16-11-04
Из: СПб
Пользователь №: 1 143



Цитата(Димон Безпарольный @ Nov 16 2017, 10:30) *
В ассемблере так часто делал. Стек разгружал


ой, "два CALL и один RET" или даже "два CALL и один JMP" стек не то что разгрузят, но "испортят" хоть в C хоть в ASM (не вернут в прежнее состояние, будет некий StackLeak который при таких N-вызовах порушит всё )
вы уверены в своих ранее написанных программах ? Или может я что-то не понимаю


--------------------
Марс - единственная планета, полностью населенная роботами (около 7 штук).
Go to the top of the page
 
+Quote Post
AlexRayne
сообщение Nov 16 2017, 08:19
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 319
Регистрация: 27-09-07
Пользователь №: 30 877



Да, это моветон.
Такое применяется только там где уже нечего беречь - выбрасывание исключений.
Go to the top of the page
 
+Quote Post
Димон Безпарольн...
сообщение Nov 16 2017, 08:30
Сообщение #6


Знающий
****

Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247



Цитата(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. Работает. Но раз моветон, применять не буду. Самому не понравилось такое решение.
Go to the top of the page
 
+Quote Post
gosha-z
сообщение Nov 16 2017, 08:30
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 327
Регистрация: 30-10-05
Пользователь №: 10 288



Цитата(Димон Безпарольный @ Nov 16 2017, 11:24) *
pop sp, Dec sp и jmp. Да, 15 лет до сих пор пашет.

И вы гарантируете одинаковость имплементации такой конструкции на всех процессорах? Что первично, inc/dec или mov?
Go to the top of the page
 
+Quote Post
novikovfb
сообщение Nov 16 2017, 08:34
Сообщение #8


Знающий
****

Группа: Участник
Сообщений: 518
Регистрация: 29-09-11
Пользователь №: 67 450



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

Эти функции использовались в С до появления в С++ исключений. Применять их стоит только в реально крайних случаях, когда нужно вернуться в указанную точку. Введение кучи флагов и их анализа для выполнения того же самого вряд ли сделает программу лучше.
Go to the top of the page
 
+Quote Post
Димон Безпарольн...
сообщение Nov 16 2017, 09:31
Сообщение #9


Знающий
****

Группа: Участник
Сообщений: 734
Регистрация: 29-11-10
Пользователь №: 61 247



Цитата(gosha-z @ Nov 16 2017, 11:30) *
И вы гарантируете одинаковость имплементации такой конструкции на всех процессорах? Что первично, inc/dec или mov?

Конечно нет. Я для 8051 писал. Мне на "все" и не надо было.
Go to the top of the page
 
+Quote Post
k155la3
сообщение Nov 16 2017, 10:05
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



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

Если "нельзя", моветон, но "оченьнадо". Оченьнадо - это авария по питанию.
Есть в моем проете один longjmp. Обеспечивает "выпрыгивание" из вектора прерывания в блок,
находящийся в начале main().
Go to the top of the page
 
+Quote Post
jcxz
сообщение Nov 16 2017, 10:24
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



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

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

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

PS: си-шными setjmp/longjmp я не пользуюсь. Пишу свои асм-функции сохранялки/переключалки стекового фрейма.
Go to the top of the page
 
+Quote Post
Hitest
сообщение Nov 17 2017, 16:15
Сообщение #12


Участник
*

Группа: Участник
Сообщений: 68
Регистрация: 2-08-17
Из: г. Чебоксары
Пользователь №: 98 608



Это даже у системных программеров под Винду (конкретно мы, группа, реализовывали свой драйвер COM порта, ...15 лет назад) было моветоном.
Можно писать как угодно коряво, но лучше красиво. В грамотных ассемблерных вставочках комментарий в каждой строке. Код должен своим видом показывать, что он правилен. Как-то так ИМХО.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 06:55
Рейтинг@Mail.ru


Страница сгенерированна за 0.01459 секунд с 7
ELECTRONIX ©2004-2016