LINUX.ORG.RU

gcc не инлайнит


0

0

gcc никак не реагирует на inline, как будто его и бе было. Соответственно, при линковке ругается, что multiple defines. По генерируемому асм-коду видно, что функция пишется в каждый объектник. По стандарту С99 должно инлайниться, да и __inline__ - чисто gcc'шный кейворд... Не работает ни inline, ни __inline__ :(. В чём бага? Чуть не забыл, это если код на С, на С++ инлайнит

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

ну не совсем рекомендация, т.к. из-за её несобладения получатся конфликты...
Код проще некуда:
f.h:
inline void foo() {
printf("foo() called\n");
}

f1.c:
#include "f.h"
int main() {
foo();
return 1;
}

f2.c:
#include "f.h"
void foo_ni() {
foo();
}

# gcc f1.c f2.c -O3
получаю ошибки о multiple defintion

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

Как всегда отца русской демократии спасет static:

f.h:

static inline void foo() { printf("foo() called\n"); }

Альтернатива -- есть некая опция в gcc, чтобы в объектник не сыпать, я не омню наизусть...

Die-Hard ★★★★★
()

Во-первых, функции не инлайняться при -O0, поэтому попробуй указать -O3.
Во-вторых, длинные функции кажется не инлайняться даже при оптимизации.

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

Опция разрещающая множественные определения: -Xlinker -zmuldefs
или -Xlinker --allow-multiple-definition для mingw.

unDEFER ★★★★★
()

Наконец, может быть стоит явно указывать стандарт?
Скажем: -std=gnu99

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

unDEFER:

> функции не инлайняться при -O0, поэтому попробуй указать -O3.

Ну это уже "чукча - не читатель, чукча - писатель!":

anonymous (*) (30.11.2005 23:38:17):

># gcc f1.c f2.c -O3 получаю ошибки о multiple defintion

> Во-вторых, длинные функции кажется не инлайняться даже при оптимизации.

Во-вторых, даже если убрать директиву inline, ошибка будет та же.

Die-Hard ★★★★★
()

2anonymous (*) (30.11.2005 21:24:43):

Еще раз, на всякий случай:

Все происходит в соответствии со всеми стандартами. Нужно указывать static, или (что, вообще говоря, не отменяет необходимости static для следования стандартам) явно запрещать генерирование объектного кода для инлайн функций.

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

я же написал, что -O3 юзается...
Про длинные не знаю, но эта функция очень короткая.
gnu99 используется gcc по дефолту, если указать явно - ничего не меняется.
В общем-то вопрос ещё и в том, кому нафиг нужны _такие_ инлайны? Хотел код, который у меня сейчас в макросы загнан, переписать под инлайны, чтобы его можно было удобнее юзать (макрос всё таки return сделать не может...), но видимо ничего хорошего из этого не выйдет :(

anonymous
()

Как же все любят углубляться в рассуждения...

А ты, дорогой анонимус, в файле .h #ifndef ananymous #define anonymous ... #endif не забыл?

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

намеренно пропустил, чтобы в форуме проще читать было. Тут нет циклических инклудов и т.п., ifndef ничего не даст

anonymous
()

>gcc никак не реагирует на inline,

это интересно почему вы так решили?

смотрим ваш код
gcc -O2 -c -S f1.c

и видим в f1.s
в функции main
movl $.LC0, (%esp)
call puts

а не вызов foo,
так что все инлайниться


> Соответственно, при линковке ругается, что multiple defines.

совершенно не соответственно,

вы же не указали "static"
static inline void foo() {
printf("foo() called\n");
}

так что gcc приходиться в код f1.c и f2.c вставить и код "foo",
чтобы разрешить внешние ссылки на "foo",

чуть ниже в f1.s можно увидеть
.globl foo
foo:
movl $.LC0, (%esp)
call puts

решение проблеммы вам уже сказали просто вставить
"static "

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

> Ну это уже "чукча - не читатель, чукча - писатель!":
Я посмотрел ещё раз на строчку компиляции сразу после поста и заметил -O3, иправляться не стал -- особого смысла не было.

> Во-вторых, даже если убрать директиву inline, ошибка будет та же.
А я не утверждал обратного.

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

> Я посмотрел ещё раз на строчку компиляции сразу после поста и заметил -O3, иправляться не стал -- особого смысла не было

даже если бы -O3 не было, что бы то ни было говорить в данной ситуации об оптимизации, о длинных/коротких ф-циях, не имеет смысла. Речь идет не об оптимизации, а об ошибках компиляции. Для правильного кода не должно быть ошибок вне зависимости от оптимизации. Орешек все разжевал.

dilmah ★★★★★
()

inline - это хинт, компилятор не обязан ему следовать. Захочет - заинлайнит, не захочет - пойдёшь нах.

А чтоб при линковке не ругалось - делай его static нах.

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

anonymous (*) (01.12.2005 8:29:52):

> а как эту самую генерацию явно запретить? в мане не нашёл :(

Да, опциями, похоже, не запретить.

Есть обратная опция, -fkeep-inline-functions.

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

однако в C++ без static отлично работает, я в танке или как? :)
всем спасибо, проблема можно сказать решена

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

> однако в C++ без static отлично работает, я в танке или как? :)

inline в C++ имеет другую семантику.

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

я знаю что такое статик, но он не имеет никакого отношения к инлайну.
Посмотрел как сделано в quake3 - да, там static inline. Вопрос снят

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