Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Ошибка при использовании inline + setjmp()
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
arhiv6
Добрый день. Решил написать простой карусельный переключатель задач. Для переключения контекста хочу использовать нелокальные переходы (setjmp, longjmp). Чтобы исключить дублирование кода, хочу небольшой участок кода вынести в отдельную функцию. Разумеется, из-за setjmp() функция должна быть встраиваемой. В gcc для этого есть специальный атрибут always_inline.
Код
static inline void loadMainContext(void) __attribute__((always_inline));
void loadMainContext(void)
{
    ...
    if (!setjmp(task_context))
        longjmp(main_context, 1);
    ...
}

Но при попытке компиляции gcc ругается:
Цитата
error: function 'loadMainContext' can never be inlined because it uses setjmp

Для себя задачу пока решил использованием дефайнов, но хочется узнать: почему компилятор не даёт мне использовать setjmp() во встраиваемой функции? Компилятор GCC 4.9.2.
Dog Pawlowa
Цитата(arhiv6 @ May 16 2016, 17:20) *
почему компилятор не даёт мне использовать setjmp() во встраиваемой функции?

потому что в вики написано:
Стандарт запрещает сохранять результат выполнения функции setjmp, накладывая ограничения на место вызова.
arhiv6
Но я не сохраняю результат выполнения. Место вызова - правильное: если я явно напишу в это месте setjmp(foo) - работает. Если я вставлю setjmp(foo) в это место с помощью define - работает. Если я вставлю setjmp(foo) в это место с помощью inline функции - не работатет (точнее компилятор просто не даст собрать). Хотя в последнем случае вместо вызова inline-функции компилятор должен (если я правильно понимаю) заменить вызов функции фактическим кодом из функции. Почему же он мне запрещает это сделать? Только лишь потому что так сказано в стандарте?

arhiv6
Собственно, на форуме программистов подсказали, что проблема в возможном нарушения стандарта. Так же подсказали возможный вариант решения:
Код
#include <setjmp.h>

jmp_buf jbuf;

extern int my_setjmp (jmp_buf env) asm ("_setjmp");

static inline int __attribute__((always_inline)) foo (void)
{
    return my_setjmp (jbuf);
}

int bar (void)
{
    return foo();
}
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.