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

 
 
> Можно ли задать inline функцию, если она определена в другом файле?
ViKo
сообщение Nov 15 2012, 11:40
Сообщение #1


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Об этом уже говорили, и выходит, что нельзя. Или все же есть способ? Или компилятор (Keil для Cortex) не дурак, сам встроит функцию, если она окажется небольшой? Например, такой:
Код
inline bool Timer_check(void) {
  return (TIM6->SR);            // Check Update Interrupt Flag in Status
}

С inline, кстати, не компилируется.
Или надо было ее написать в виде макро?
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 18)
MrYuran
сообщение Nov 15 2012, 11:54
Сообщение #2


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(ViKo @ Nov 15 2012, 15:40) *
Или надо было ее написать в виде макро?

Написать static inline и расположить в .h файле


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
yes
сообщение Nov 15 2012, 11:54
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 198
Регистрация: 23-12-04
Пользователь №: 1 640



а как компилятор узнает, какой код ему инлайнить?
в h файле ее можно описать и инклюдить и в этот файл и в другой

Go to the top of the page
 
+Quote Post
ViKo
сообщение Nov 15 2012, 12:10
Сообщение #4


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Если последний вопрос ко мне, то у меня есть заголовочный файл (упрощенно говоря) fun.h, который подключается к main.c файлу, и где был описан прототип функции:
bool Timer_check(void);
А если добавить inline и к прототипу, и к определению функции, то не компилируется.
А если всю функцию перенести в заголовочный файл fun.h, то работает, независимо, static или без... только размерчик получился больше (!), чем когда функция была определена в fun.c файле. Code = 29744 вместо 29224.

upd. не ту функцию показал, поправил.

P.S. А если добавляю inline только к прототипу или к определению, то компилируется, но уже с размером 29232!
(А-а-а-а-а! зачем же я пьянствовал вчера, надо было бы сегодня!)
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Nov 15 2012, 12:34
Сообщение #5


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(ViKo @ Nov 15 2012, 15:10) *
размерчик получился больше (!), чем когда функция была определена в fun.c файле. Code = 29744 вместо 29224.

Дался Вам этот кейл... В ГЦЦ
Код
static inline __attribute__((always_inline)) void somefunc(const int argument)

И всё. Ничего не растет без спроса у хозяина битов sm.gif
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Nov 15 2012, 12:53
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(_Pasha @ Nov 15 2012, 14:34) *
Дался Вам этот кейл... В ГЦЦ

Но функция в другом файле находится не может?
Go to the top of the page
 
+Quote Post
ViKo
сообщение Nov 15 2012, 13:15
Сообщение #7


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(_Pasha @ Nov 15 2012, 15:34) *
Дался Вам этот кейл... В ГЦЦ

И в Keil есть такие штуки (эквивалентны):
__attribute__((always_inline))
__forceinline
Добавляются к прототипу функции.
Go to the top of the page
 
+Quote Post
yes
сообщение Nov 15 2012, 13:27
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 2 198
Регистрация: 23-12-04
Пользователь №: 1 640



Цитата(ViKo @ Nov 15 2012, 17:15) *
И в Keil есть такие штуки (эквивалентны):
__attribute__((always_inline))
__forceinline
Добавляются к прототипу функции.


это к функциям в файле относится, у gcc тоже есть always_inline

http://gcc.gnu.org/onlinedocs/gcc/Inline.html

Цитата(ViKo @ Nov 15 2012, 16:10) *
Если последний вопрос ко мне, то у меня есть заголовочный файл (упрощенно говоря) fun.h, который подключается к main.c файлу, и где был описан прототип функции:


для инлайна ему нужен не прототип, а код функции. вопрос был риторический

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

-----------

btw: static к определению фукнции (или переменной) дописывают чтобы не загаживать пространство имен, она как бы локальная получается и линкер такой функции не видит (это для больших проектов полезно)
у фукнции или не стековой (обычно называют глобальной) переменной это больше ни на что не влияет.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Nov 15 2012, 13:27
Сообщение #9


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(yes @ Nov 15 2012, 16:23) *
это к функциям в файле относится, у gcc тоже есть always_inline

А зачем они тогда вообще нужны, чем inline не годится? wacko.gif
А, наверное, задавать принудительно, даже если это и не оптимально.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Nov 15 2012, 13:40
Сообщение #10


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(ViKo @ Nov 15 2012, 17:27) *
А зачем они тогда вообще нужны, чем inline не годится? wacko.gif
А, наверное, задавать принудительно, даже если это и не оптимально.

Патамушо always_inline не помещает тело функции в объектник если функция ни разу не вызывалась. А без него - помещает.
Go to the top of the page
 
+Quote Post
toweroff
сообщение Nov 15 2012, 16:53
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Цитата(_Pasha @ Nov 15 2012, 17:40) *
Патамушо always_inline не помещает тело функции в объектник если функция ни разу не вызывалась. А без него - помещает.

объектник - это одно. Линкер разве помещает ее в код, если она не вызывалась ни разу?
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Nov 15 2012, 17:21
Сообщение #12


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(toweroff @ Nov 15 2012, 20:53) *
объектник - это одно. Линкер разве помещает ее в код, если она не вызывалась ни разу?

Я неправильно выразился.
Инлайнит независимо от уровня оптимизации, так по стандарту.
Go to the top of the page
 
+Quote Post
XVR
сообщение Nov 16 2012, 07:47
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847



Цитата(yes @ Nov 15 2012, 17:27) *
по-моему в нынешних компиляторах нет такой фазы, чтобы шарится по всем объектникам и искать там коды для инлайнов
Не совсем так. Есть режим компиляции (в gcc он называется LTO, в других компиляторах whole program optimization или нечто подобное), который позволяет заинлайнить функцию, даже если ее тело находится в другой единице компиляции и даже если ей там inline не писали.
Но реализуется это конечно не поиском кода в объектниках (в этом режиме в объектниках вообще кода может и не быть) rolleyes.gif
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Nov 16 2012, 10:33
Сообщение #14


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(ViKo @ Nov 15 2012, 16:10) *
А если всю функцию перенести в заголовочный файл fun.h, то работает, независимо, static или без...

Стоит подключить fun.h к нескольким модулям, и сразу станет понятен смысл static.
Без него линкер выдаст ошибку "Multiple definition" - одноименный объект создается в разных модулях.


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
ViKo
сообщение Nov 16 2012, 10:41
Сообщение #15


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(MrYuran @ Nov 16 2012, 13:33) *
Стоит подключить fun.h к нескольким модулям, и сразу станет понятен смысл static.
Без него линкер выдаст ошибку "Multiple definition" - одноименный объект создается в разных модулях.

Это заменяет
Код
#ifndef FUN_H
#define FUN_H
...
#endif

?
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Nov 16 2012, 11:19
Сообщение #16


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

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



не совсем
Вам уже про LTO советовали, а я повторюсь, что и у Кейла есть галочка типа "link-time code generation" - это фактически аналог LTO от gcc.
В таком режиме все функции рассматриваются компилятором как static...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
ViKo
сообщение Nov 16 2012, 11:49
Сообщение #17


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(demiurg_spb @ Nov 16 2012, 14:19) *
не совсем
Вам уже про LTO советовали, а я повторюсь, что и у Кейла есть галочка типа "link-time code generation" - это фактически аналог LTO от gcc.
В таком режиме все функции рассматриваются компилятором как static...

Не галочка - опция.
Цитата
--ltcg
This option instructs the compiler to create objects in an intermediate format so that Link-Time Code Generation (LTCG) optimizations can be performed. The optimizations applied include cross-module inlining to improve performance, and sharing of base addresses to reduce code size.

Note
This option might significantly increase link time and memory requirements. For large applications it is recommended that you do the code generation in partial link steps with a subset of the objects.

The LTCG feature is deprecated. As an alternative ARM recommends you use the --multifile option.

Example
The following example shows how to use the --ltcg option.

armcc -c --ltcg file1.c
armcc -c --ltcg file2.c
armlink --ltcg file1.o file2.o -o prog.axf


Из галочек есть
Use Cross-module optimization

Понял, нужно читать помощь по Кейлу! sm.gif
Go to the top of the page
 
+Quote Post
MrYuran
сообщение Nov 16 2012, 11:57
Сообщение #18


Беспросветный оптимист
******

Группа: Свой
Сообщений: 4 640
Регистрация: 26-12-07
Из: Н.Новгород
Пользователь №: 33 646



Цитата(ViKo @ Nov 16 2012, 14:41) *
Это заменяет

?

Нет, это просто защита от повторного включения внутри единицы компиляции, коей является c/cpp файл.
аналог #pragma once

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


--------------------
Программирование делится на системное и бессистемное. ©Моё :)
— а для кого-то БГ — это Bill Gilbert =)
Go to the top of the page
 
+Quote Post
ViKo
сообщение Nov 16 2012, 12:04
Сообщение #19


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Цитата(MrYuran @ Nov 16 2012, 14:57) *
Нет, это просто защита от повторного включения внутри единицы компиляции, коей является c/cpp файл.
аналог #pragma once

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

То, что я показал, позволяет мне в одном общем file.h собрать заголовочные файлы для всех составляющих проекта, и потом подключать только его во все files.c.
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 20th June 2025 - 02:21
Рейтинг@Mail.ru


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