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

 
 
> Определение inline функции, Обязательно в хедере?
sonycman
сообщение Dec 13 2008, 10:38
Сообщение #1


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Есть несколько файлов исходника:
LCD.h с объявлением функции:
Код
inline    void    lcdClearScreen();

LCD.c с определением:
Код
inline    void    lcdClearScreen()
{
    lcdWriteCommand(0x01);
};

и вызов этой функции из третьего файла I2C.c:
Код
#include    "lcd.h"
...
lcdClearScreen();

Что-то первый раз столкнулся с тем, что, при компиляции файла I2C.c, компилер выдаёт ошибку про отсутствие определения этой функции 07.gif
Вышел из положения включением определения функции в хедер LCD.h:
Код
inline    void    lcdClearScreen()
{
    lcdWriteCommand(0x01);
};

Получается, inline функции необходимо определять сразу при объявлении?
Go to the top of the page
 
+Quote Post
2 страниц V   1 2 >  
Start new topic
Ответов (1 - 23)
Сергей Борщ
сообщение Dec 13 2008, 14:38
Сообщение #2


Гуру
******

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



Цитата(sonycman @ Dec 13 2008, 12:38) *
Получается, inline функции необходимо определять сразу при объявлении?
Нет, не так. Просто компилятор должен иметь тело функции на момент встраивания. Иначе откуда он узнает, что именно встраивать? А откуда он возьмет тело - из заголовочного файла или из начала исходника, в котором встретил точку встраивания или из середины этого исходника - не важно. Обычно тело inline-функции размещают в заголовочном файле, чтобы его можно было встроить в любом исходнике, куда подключен заголовок. Ничто не мешает совместить объявление и определение такой функции, что часто и делается для небольших по размеру функций.


--------------------
На любой вопрос даю любой ответ
"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
sonycman
сообщение Dec 13 2008, 20:29
Сообщение #3


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



А, понятно smile.gif
То есть компилер за один проход должен создать объектный файл? А для не-встраиваемых внешних функций, определённых в других файлах, генерируются простые обращения в виде вызовов, а уже линкер потом записывает конкретные адреса?

Спасибо! a14.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Dec 14 2008, 00:36
Сообщение #4


Гуру
******

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



Цитата(sonycman @ Dec 13 2008, 22:29) *
То есть компилер за один проход должен создать объектный файл? А для не-встраиваемых внешних функций, определённых в других файлах, генерируются простые обращения в виде вызовов, а уже линкер потом записывает конкретные адреса?
Да, именно так. Причем для встраиваимых функций и обращений не будет. Все тело будет вставлено туда, где для обычной функции был бы вызов.


--------------------
На любой вопрос даю любой ответ
"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
Rash
сообщение Jun 2 2012, 16:56
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 639
Регистрация: 5-09-05
Пользователь №: 8 231



возникла таже проблема, но так и не понял как её решить.
Можно пример кода, где и что объявлять?
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Jun 2 2012, 17:13
Сообщение #6


Гуру
******

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



Цитата(Rash @ Jun 2 2012, 19:56) *
Можно пример кода, где и что объявлять?


Объявлять можно в h-файле
Код
#define LED_PORT PORTB
#pragma inline=forced
inline void LedOn() {
    LED_PORT|=(1<<LED_PIN);
}

или так:
Код
#define PRAGMA(x) _Pragma( #x )
#define INLINE PRAGMA( inline=forced ) static

INLINE void LedOn() {
    LED_PORT|=(1<<LED_PIN);
}

Go to the top of the page
 
+Quote Post
Rash
сообщение Jun 2 2012, 17:35
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 639
Регистрация: 5-09-05
Пользователь №: 8 231



спасибо, т.е. тело функции должно быть в h файле?
Может можно сделать что бы inline объявления были в h, а реализация в С файлах
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Jun 2 2012, 19:23
Сообщение #8


Гуру
******

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



Цитата(Rash @ Jun 2 2012, 20:35) *
т.е. тело функции должно быть в h файле?

Может быть и в с-файле:
Код
#pragma inline=forced
inline static void OffLed()
{
    PORTD.DIRSET=1;
    PORTD.OUTCLR=1;
}


int main() {
    OffLed();


Цитата(Rash @ Jun 2 2012, 20:35) *
Может можно сделать что бы inline объявления были в h, а реализация в С файлах

У меня такое сделать не получалось (а зачем оно надо?): линкер ругается чем то наподобии "Undefined OffLed". Видимо это неспроста.
Go to the top of the page
 
+Quote Post
Rash
сообщение Jun 2 2012, 20:46
Сообщение #9


Знающий
****

Группа: Свой
Сообщений: 639
Регистрация: 5-09-05
Пользователь №: 8 231



Цитата(_Артём_ @ Jun 2 2012, 22:23) *
У меня такое сделать не получалось (а зачем оно надо?): линкер ругается чем то наподобии "Undefined OffLed". Видимо это неспроста.


Да не получается. Перепробовал наверное вариантов 20, так и не нашёл как.
Удобно в С файлах код, а в h описание ф-ций.
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jun 3 2012, 05:34
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(Rash @ Jun 2 2012, 23:46) *
Да не получается.

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


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
VladislavS
сообщение Jun 3 2012, 05:35
Сообщение #11


Местный
***

Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140



Что-то вы проблему на ровном месте придумали. Чтобы встроить функцию в месте вызова она должна быть определена в той же единице компиляции, где происходит вызов. Грубо говоря, в том же c-файле, либо в подключенном h-файле, что для компилятора по сути одно и то же.
Go to the top of the page
 
+Quote Post
Rash
сообщение Jun 3 2012, 13:43
Сообщение #12


Знающий
****

Группа: Свой
Сообщений: 639
Регистрация: 5-09-05
Пользователь №: 8 231



не знаю проблема или нет, но я хотел бы видеть вой код так:

описание инлайн функции в файл1.h, код выполнения в файл1.с, а вызов функции, т.е. её встраивание было в файл2.с.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jun 3 2012, 13:53
Сообщение #13


Гуру
******

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



QUOTE (Rash @ Jun 3 2012, 16:43) *
не знаю проблема или нет
Проблема. Потому что во время компиляции файл2.c компилятор понятия не имеет ни о существовании файл1.c, ни о его содержимом и, соответветственно, о том, что же именно ему нужно вставить в место вызова этой функции. Чтобы он имел возможность встроить, тело функции должно быть ему доступно, а значит располагаться либо в файл2.c, либо в любом файле, включенном в него директивой #include. Других вариантов нет.

Хотите красоты - делайте функцию невстраиваемой. По этому пути пошли создатели CMSIS. В ней, чтобы записать одно значение в один регистр вызывается функция со всеми вытекающими тормозами и раздутием кода.


--------------------
На любой вопрос даю любой ответ
"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
_Артём_
сообщение Jun 3 2012, 21:39
Сообщение #14


Гуру
******

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



Цитата(Сергей Борщ @ Jun 3 2012, 16:53) *
Хотите красоты - делайте функцию невстраиваемой. По этому пути пошли создатели CMSIS.

Это красота?
В CMSIS полно inline-функций.
В чём неправильность их пути?

Цитата(Сергей Борщ @ Jun 3 2012, 16:53) *
В ней, чтобы записать одно значение в один регистр вызывается функция со всеми вытекающими тормозами и раздутием кода.

А как лучше делать?

Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 3 2012, 21:59
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(_Артём_ @ Jun 4 2012, 01:39) *
А как лучше делать?

Лучше просто писать в регистр.
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Jun 3 2012, 22:17
Сообщение #16


Гуру
******

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



Цитата(aaarrr @ Jun 4 2012, 00:59) *
Лучше просто писать в регистр.

Как просто...
А почему они не пишут "просто в регистр"?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 3 2012, 22:20
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(_Артём_ @ Jun 4 2012, 02:17) *
А почему они не пишут "просто в регистр"?

От большого ума, надо полагать. Увы, вижу массу примеров, как на пустом месте создается "библиотека", бессмысленная и беспощадная. CMSIS - как раз один из таких случаев.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jun 4 2012, 04:21
Сообщение #18


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

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



Мне кажется, тут разные люди говорят о разных CMSIS-ах. Та часть, которая от собственно ARM - она состоит вообще исключительно из *.h файлов с инлайн-функциями и определениями структур. (Это файлы core_cm0.h, core_cm3.h, core_cm4.h, core_cm4_simd.h, core_cmFunc.h, core_cmInstr.h.) Остальное - это уже от производителя конкретного контроллера. И здесь уже конечно бывают наворотыsm.gif
Кстати, ST здесь на удивление скромны - всего-лишь startup_xxx.s и system_xxx.c. Остальное - опять же хидеры. Зато уж в своей StdPeriph библиотеке они уже оторвались по полнойsm.gif



--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Jun 4 2012, 10:18
Сообщение #19


Гуру
******

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



Цитата(AHTOXA @ Jun 4 2012, 07:21) *
Зато уж в своей StdPeriph библиотеке они уже оторвались по полнойsm.gif

И не только они: NXP, EFM - тоже самое делают.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 4 2012, 12:33
Сообщение #20


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(AHTOXA @ Jun 4 2012, 08:21) *
Кстати, ST здесь на удивление скромны - всего-лишь startup_xxx.s и system_xxx.c. Остальное - опять же хидеры. Зато уж в своей StdPeriph библиотеке они уже оторвались по полнойsm.gif

Мне хватило просмотра кода вычисления делителя UART - остальную часть библиотек ST забраковал не глядя.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jun 4 2012, 12:41
Сообщение #21


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

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



Цитата(aaarrr @ Jun 4 2012, 18:33) *
Мне хватило просмотра кода вычисления делителя UART - остальную часть библиотек ST забраковал не глядя.

Да, это шедеврsm.gif Но это не CMSIS, вот я о чём.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
scifi
сообщение Jun 4 2012, 12:43
Сообщение #22


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(aaarrr @ Jun 4 2012, 16:33) *
Мне хватило просмотра кода вычисления делителя UART - остальную часть библиотек ST забраковал не глядя.

+1. STишная библиотека вызывает стойкое отвращение.
Причём особого смысла в её существовании не вижу: руководство по МК всё равно нужно читать, а для облегчения программирования регистров можно придумать очень небольшой набор макросов. Регистры МК довольно понятные. А в сложных случаях (таймеры) попытка сделать обёртку для упрощения может всё только запутать. Лучше в руководстве всё подробно расписать.
Go to the top of the page
 
+Quote Post
Dog Pawlowa
сообщение Jun 4 2012, 12:47
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 2 702
Регистрация: 14-07-06
Пользователь №: 18 823



Цитата(scifi @ Jun 4 2012, 15:43) *
STишная библиотека вызывает стойкое отвращение.
Причём особого смысла в её существовании не вижу

Я вот тоже отвращение испытываю, но подергался-подергался и работаю с библиотекой.
Не критично. Но зло берет. Смайлик неудовлетворения.


--------------------
Уходя, оставьте свет...
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jun 4 2012, 13:11
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(AHTOXA @ Jun 4 2012, 16:41) *
Да, это шедеврsm.gif Но это не CMSIS, вот я о чём.

Дык, в CMSIS тоже всплывают косяки периодически.

Цитата(Dog Pawlowa @ Jun 4 2012, 16:47) *
...подергался-подергался и работаю с библиотекой.

У меня были такие мысли, пока окучивал USB на STM32F40x. Сделано как будто специально, чтобы максимально неудобно софт писать было sad.gif
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 24th July 2025 - 23:08
Рейтинг@Mail.ru


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