Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: GCC - inline не работает
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > GNU/OpenSource средства разработки
EugeNNe
GCC. Определяю функцию:

static inline void Reset(void) __attribute__((always_inline));

Ну не хочет ГЦЦ фукцию как inline делать. В чём может быть проблема?
AHTOXA
Судя по названию (Reset), возможно, где-то используется адрес этой функции? Например, в таблице векторов?
EugeNNe
Цитата(AHTOXA @ Jun 8 2009, 15:32) *
Судя по названию (Reset), возможно, где-то используется адрес этой функции? Например, в таблице векторов?


Ну вообще говоря, эта функция вызывается в прерывании таймера.
Сергей Борщ
Цитата(BigBolt @ Jun 8 2009, 14:29) *
В чём может быть проблема?
Попробуйте static __attribute__((always_inline)) inline void Reset(void); т.е. поставить __attribute__((always_inline)) перед void Reset().
aesok
Цитата(BigBolt @ Jun 8 2009, 15:29) *
GCC. Определяю функцию:

static inline void Reset(void) __attribute__((always_inline));


То что Вы привели не являеться определением функции. Это описание функции.

Пожалуйста приведите, для тех у кого отсутствуют телепатические способности, как и каком файле Вы определяете функцию Reset, и как и в каком файле Вы ее используете.

Анатолий.
ARV
а вот хотел спросить, какую роль играет, если играет, место указания атрибутов для функций и переменных? встречал и перед идентификатором, и после, и в разных комбинациях с static и т.п. в документации тоже порой по-разному...
я вот всегда определяю по такому шаблону:
[static] [inlinne] [type_of_result] [__attribute__(())] identificator [()];
demiurg_spb
На мой взгляд атрибут лучше приписывать поближе к имени функции при её описании.
А до или после - это роли не играет, главное выработать свой стиль...
klen
чтото мне кажется что не любой код функции зайнланить можно в принципе.
код функции в студию
EugeNNe
Пожалуста код:

static inline void Reset(void) __attribute__((always_inline));

Reset()
{
PORTD &=~(1<<PD7);
_delay_loop_2(1843);
PORTD |=(1<<PD7);
asm volatile ("jmp 0");
}
forever failure
Должно всё инлайнится. У меня таких функций пруд-пруди, все инлайнятся.
Кстати, не раскрыты следующие темы:
- версии компилятора;
- уровня оптимизации и ключей компиляции;
- контекста вызова функции;
- для пущей ясности, было бы очь хорошо исходный код и дизассемблерный листинг того, что получается.
Alex B._
Цитата(BigBolt @ Jun 9 2009, 09:02) *
Пожалуста код:

Имхо не надо разделять прототип и реализацию. Сделайте вот так:
Код
static inline void  Reset(void) __attribute__((always_inline))
{              
      PORTD &=~(1<<PD7);        
      _delay_loop_2(1843);      
      PORTD |=(1<<PD7);          
      asm volatile ("jmp 0");    
}

А еще лучше сделать так:
Код
inline extern void  Reset(void)
{
    // ....
}

Тогда функция будет инлайнится всегда, при любом уровне оптимизации (конечно, если вы захотите вызвать ее по указателю - то будет создан экземпляр)
EugeNNe
Цитата(Alex B._ @ Jun 9 2009, 10:12) *
Имхо не надо разделять прототип и реализацию. Сделайте вот так:
Код
static inline void  Reset(void) __attribute__((always_inline))
{              
      PORTD &=~(1<<PD7);        
      _delay_loop_2(1843);      
      PORTD |=(1<<PD7);          
      asm volatile ("jmp 0");    
}

А еще лучше сделать так:
Код
inline extern void  Reset(void)
{
    // ....
}

Тогда функция будет инлайнится всегда, при любом уровне оптимизации (конечно, если вы захотите вызвать ее по указателю - то будет создан экземпляр)


Всё заработало. Посмотрел как сделана библиотека delay.h. Действительно прототип и реализация в одном месте. У меня же прототип был в хидере, а реализация в сишном файле. Запихал всё в один файл и заработало...
Вы же подтвердили что так и надо делать... В доке ничего не сказано такого
Сергей Борщ
Цитата(BigBolt @ Jun 9 2009, 09:34) *
У меня же прототип был в хидере, а реализация в сишном файле. Запихал всё в один файл и заработало...
Вы же подтвердили что так и надо делать... В доке ничего не сказано такого
Вот чтобы не плодились очередные мифы, уточню. Компилятор должен знать, что именно инлайнить в точке вызова. То есть к тому моменту, когда он встречает вызов функции, он уже должен был просмотреть определение этой функции. Где он "видел" это определение - в заголовочном файле или в этом же сишном - абсолютно без разницы. Если же тело находится в другом сишном файле - компилятор просто физически не может знать, какой именно код вставлять в точку встраивания. Это настолько очевидно, что даже и мысли не возникало это объяснять, и что кто-то может пытаться делать иначе. То есть если вы функцию используете только в одном с-файле, то ее тело может быть в этом же файле, не обязательно в заголовочном (это полезно в плюсах для функций-членов). Важно, чтобы это тело было доступно в момент встраивания.
ARV
и все-таки, есть разница между

... __attribute__((always_inline)) my_foo(void);

и

... my_foo(void) __attribute__((always_inline));

?

мое мнение - есть. распарсивая строку компилятор "у себя в мозгах" сразу укладывает данные по порядку их следования, поэтому если атрибут стоит левее имени, то к этому имени сразу применяются все левостоящие атрибуты, если правее - они могут быть проигнорированы, если компилятор сочтет достаточным того, что уже знает. в частности, по-моему есть разница между

PROGMEM uint8_t *var;

и

uint8_t PROGMEM *var;

или я не прав?
Tiro
Цитата(BigBolt @ Jun 9 2009, 09:34) *
Всё заработало. Посмотрел как сделана библиотека delay.h. Действительно прототип и реализация в одном месте. У меня же прототип был в хидере, а реализация в сишном файле. Запихал всё в один файл и заработало...
Вы же подтвердили что так и надо делать... В доке ничего не сказано такого


Все есть в доке, надо только прочесть 5.36 An Inline Function is As Fast As a Macro
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.