Перейти к содержанию
    

Ошибка при использовании inline + setjmp()

Добрый день. Решил написать простой карусельный переключатель задач. Для переключения контекста хочу использовать нелокальные переходы (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.

Изменено пользователем arhiv6

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

почему компилятор не даёт мне использовать setjmp() во встраиваемой функции?

потому что в вики написано:

Стандарт запрещает сохранять результат выполнения функции setjmp, накладывая ограничения на место вызова.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Собственно, на форуме программистов подсказали, что проблема в возможном нарушения стандарта. Так же подсказали возможный вариант решения:

#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();
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...