LINUX.ORG.RU

inline в pure C


0

0

Вопрос достаточно, наверное глупый:

1) inline/__inline__ в C --- это чисто фишка gcc или часто встречающаяся штука?

2) как можно заставить gcc встраивать функции из другого файла?

Имеется в виду следующую ситуацию:

===file1.c

#include "file2.h"

void f (void)

{

inl_f ();

}

===file2.h

__inline__ inl_f (void);

===file2.c

#include "file2.h"

__inline__ inl_f (void) { some_thing (); }

У меня что--то встраивается только если в file2.h будет не объявление, а сама функция. Не нравиться мне это... Можно ли заставить работать как сейчас?

anonymous

Если реализация функции описана в файле, с которым программа линкуется, а не который является заголовочным, то инлайн не прокатит.

А что касается inline вообще, так это стандарт C99.

Впрочем можешь почитать дискуссию в гугл группе:

http://groups-beta.google.com/group/comp.lang.c/browse_thread/thread/84fbd61f...

anonymous
()
Ответ на: комментарий от anonymous

> Если реализация функции описана в файле, с которым программа линкуется, а не который является заголовочным, то инлайн не прокатит.

то есть единственный способ:

===file2.h

__inline__ void inlf (void) {qqq();}

> А что касается inline вообще, так это стандарт C99.

а много компиляторов поддерживают C99??? Я увидел только gcc, icc, sdcc.

anonymous
()
Ответ на: комментарий от anonymous

И вопрос, тогда получается, что если я использую этот заголовочный файл более чем в одном месте у меня получиться multiple definition. Этого можно как--то по нормальному избежать?

anonymous
()
Ответ на: комментарий от anonymous

>И вопрос, тогда получается, что если я использую этот заголовочный файл более чем в одном месте у меня получиться multiple definition. Этого можно как--то по нормальному избежать?

Да можно - нормальным написанием заголовочных файлов.

cvv ★★★★★
()
Ответ на: комментарий от cvv

> Да можно - нормальным написанием заголовочных файлов.

А можно мааааахонький примерчик? Пожалуйста...

Сейчас сделал по кривому:

===file2.h

#ifndef C__FILE2__

__inline__ void inlf (void) {q();}

#endif

===file2.c

#define C__FILE2__

#include "file2.h"

Но что делать, если file2.h надо будет включить еще в одном месте --- я не знаю...

anonymous
()
Ответ на: комментарий от anonymous

>А можно мааааахонький примерчик? Пожалуйста...

>Сейчас сделал по кривому:

===file2.h

#ifndef C__FILE2__

__inline__ void inlf (void) {q();}

#endif

===file2.c

#define C__FILE2__

#include "file2.h"

>Но что делать, если file2.h надо будет включить еще в одном месте --- я не знаю...

Для начала посмотри как другие делают: поройся в /usr/include - там масса рульных екзамплов

а вообщето для чистого С что-то типа:

/**file2.h*/

#ifndef __FILE2_H
#define __FILE2_H

__inline__ void inlf (void) {q();}

#endif


/**file2.c*/

#include "file2.h"


Тоесть если ты включиш такой file2.h 10 раз подряд в одном файле то ето будет еквивалентно *1* включению и ты никогда не получиш multiple definition

cvv ★★★★★
()
Ответ на: комментарий от cvv

> То есть если ты включиш такой file2.h 10 раз подряд в одном файле то ето будет еквивалентно *1* включению и ты никогда не получиш multiple definition

Про "стражей включения"

#ifndef H__FILE1__

#define H__FILE1__

я знаю.

Я имею ввиду следующую ситуация:

gcc file1.c file2.o file3.o

где file1, file2 и file3 включяют file2.h с inline функцией.

Что делать в этом случае?

/usr/include смотрел, но что бы там использовались inline функции в чистом C не нашел :(.

anonymous
()
Ответ на: комментарий от anonymous

>Про "стражей включения"

>#ifndef H__FILE1__

>#define H__FILE1__

>я знаю.

Вообщето раньше между тем что привёл ты и привёл я существовала принципиальная разница, тоесть препроцессор вёл себя совершенно по разному иначе бы в екзампле я оставил твои Макросы.

>Я имею ввиду следующую ситуация:

>gcc file1.c file2.o file3.o

>где file1, file2 и file3 включяют file2.h с inline функцией.

>Что делать в этом случае?

В етом случае всё прекрасно никакими multiple definition здесь и не пахнет. Всё должно нормально компилится линковатся и работать.

ещё можеш заюзать static для указания локальности твоей inline ф-и хотя ето по моему излишне

>/usr/include смотрел, но что бы там использовались inline функции в чистом C не нашел :(.

Возможно. inline в чистом С весчь не распостранённая

cvv ★★★★★
()

Я, вообще-то, не эксперт в данном вопросе. Я широко использую inline, когда надоедает думать (и время поджимает), но -- только локально, в тех же файлах.

Пара наблюдений:

Насколько я понял, gcc реагирует на директиву inline так: он инлайнит функцию в файле, и заодно "на всякий случай" пихает ее в объектный файл. Т.е. при линковке такие функции из других файлов будут обычными out-of-line функциями.

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

Вообще, icc инлайнит ЗНАЧИТЕЛЬНО грамотнее. В частности, icc вполне себе инлайнит рекурсивные функции, а gcc говорит, что не может.

Die-Hard ★★★★★
()
Ответ на: комментарий от cvv

> Вообщето раньше между тем что привёл ты и привёл я существовала принципиальная разница, тоесть препроцессор вёл себя совершенно по разному иначе бы в екзампле я оставил твои Макросы.

Ну это я просто опускал как вещь само--собой разумеющуюся.

> В етом случае всё прекрасно никакими multiple definition здесь и не пахнет. Всё должно нормально компилится линковатся и работать.

В том--то и дело, что проблема есть:

===file1.c

#include "file2.h"

#include "stdio.h"

int main (void)

{ printf("%d %d\n", q (), q2 (q ()) ); }

===file2.c #include "file2.h"

int q2 (int r) { return r+3; }

===file2.h #ifndef H__FILE2 #define H__FILE2

inline int q (void) {return 3;} int q2 (int);

#endif

===stdin $ gcc -c file1.c

$ gcc -c file2.c

$ gcc file1.o file2.o

file2.o(.text+0x0): In function `q':

: multiple definition of `q'

file1.o(.text+0x0): first defined here

collect2: ld returned 1 exit status

:-(

anonymous
()
Ответ на: комментарий от cvv

> ещё можеш заюзать static для указания локальности твоей inline ф-и хотя ето по моему излишне

Sorry, не увидел. Так все отлично работает.

Спасибо. ^^

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.