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

 
 
 
Reply to this topicStart new topic
> GCC - inline не работает
EugeNNe
сообщение Jun 8 2009, 11:29
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 424
Регистрация: 6-03-06
Из: Н.Новгород
Пользователь №: 14 997



GCC. Определяю функцию:

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

Ну не хочет ГЦЦ фукцию как inline делать. В чём может быть проблема?
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jun 8 2009, 11:32
Сообщение #2


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Судя по названию (Reset), возможно, где-то используется адрес этой функции? Например, в таблице векторов?


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
EugeNNe
сообщение Jun 8 2009, 11:58
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 424
Регистрация: 6-03-06
Из: Н.Новгород
Пользователь №: 14 997



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


Ну вообще говоря, эта функция вызывается в прерывании таймера.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 8 2009, 12:21
Сообщение #4


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(BigBolt @ Jun 8 2009, 14:29) *
В чём может быть проблема?
Попробуйте static __attribute__((always_inline)) inline void Reset(void); т.е. поставить __attribute__((always_inline)) перед void Reset().


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
aesok
сообщение Jun 8 2009, 13:32
Сообщение #5


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(BigBolt @ Jun 8 2009, 15:29) *
GCC. Определяю функцию:

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


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

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

Анатолий.

Сообщение отредактировал aesok - Jun 8 2009, 13:33
Go to the top of the page
 
+Quote Post
ARV
сообщение Jun 8 2009, 14:48
Сообщение #6


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

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



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


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jun 8 2009, 16:16
Сообщение #7


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



На мой взгляд атрибут лучше приписывать поближе к имени функции при её описании.
А до или после - это роли не играет, главное выработать свой стиль...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
klen
сообщение Jun 8 2009, 20:19
Сообщение #8


бессмертным стать можно тремя способами
*****

Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912



чтото мне кажется что не любой код функции зайнланить можно в принципе.
код функции в студию
Go to the top of the page
 
+Quote Post
EugeNNe
сообщение Jun 9 2009, 05:02
Сообщение #9


Местный
***

Группа: Участник
Сообщений: 424
Регистрация: 6-03-06
Из: Н.Новгород
Пользователь №: 14 997



Пожалуста код:

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

Reset()
{
PORTD &=~(1<<PD7);
_delay_loop_2(1843);
PORTD |=(1<<PD7);
asm volatile ("jmp 0");
}
Go to the top of the page
 
+Quote Post
forever failure
сообщение Jun 9 2009, 05:36
Сообщение #10


Местный
***

Группа: Участник
Сообщений: 256
Регистрация: 6-03-05
Из: Екатеринбург
Пользователь №: 3 112



Должно всё инлайнится. У меня таких функций пруд-пруди, все инлайнятся.
Кстати, не раскрыты следующие темы:
- версии компилятора;
- уровня оптимизации и ключей компиляции;
- контекста вызова функции;
- для пущей ясности, было бы очь хорошо исходный код и дизассемблерный листинг того, что получается.
Go to the top of the page
 
+Quote Post
Alex B._
сообщение Jun 9 2009, 06:12
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 943
Регистрация: 6-07-04
Из: Санкт-Петербург
Пользователь №: 274



Цитата(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)
{
    // ....
}

Тогда функция будет инлайнится всегда, при любом уровне оптимизации (конечно, если вы захотите вызвать ее по указателю - то будет создан экземпляр)
Go to the top of the page
 
+Quote Post
EugeNNe
сообщение Jun 9 2009, 06:34
Сообщение #12


Местный
***

Группа: Участник
Сообщений: 424
Регистрация: 6-03-06
Из: Н.Новгород
Пользователь №: 14 997



Цитата(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. Действительно прототип и реализация в одном месте. У меня же прототип был в хидере, а реализация в сишном файле. Запихал всё в один файл и заработало...
Вы же подтвердили что так и надо делать... В доке ничего не сказано такого
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 9 2009, 08:15
Сообщение #13


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



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


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
ARV
сообщение Jun 9 2009, 09:40
Сообщение #14


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

Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581



и все-таки, есть разница между

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

и

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

?

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

PROGMEM uint8_t *var;

и

uint8_t PROGMEM *var;

или я не прав?


--------------------
Я бы взял частями... но мне надо сразу.
Go to the top of the page
 
+Quote Post
Tiro
сообщение Jun 9 2009, 10:16
Сообщение #15


Знающий
****

Группа: Свой
Сообщений: 781
Регистрация: 3-10-04
Из: Санкт-Петербург
Пользователь №: 768



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


Все есть в доке, надо только прочесть 5.36 An Inline Function is As Fast As a Macro
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 02:11
Рейтинг@Mail.ru


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