Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
goodmansem
Зарегистрирован: 15.08.2006 Сообщения: 9 Откуда: Томск
|
Добавлено: Вт Окт 28 2008 13:19 Заголовок сообщения: проблема с inline-функциями |
|
|
Появилась вот такая проблема: есть 3 файла..
Код: |
//------------------------
inl.h
//------------------------
class A
{
public:
void init();
};
//------------------------
inl.cpp
//------------------------
#include "inl.h"
#include <stdio.h>
inline void A::init()
{
printf("init\n");
}
//------------------------
main.cpp
//------------------------
#include "inl.h"
int main()
{
A a;
a.init();
return 0;
}
|
Когда компилируется проект, то линковщик выдает ошибку, что не найдена внешняя функция init().
Почему такое происходит? Если убрать ключевое слово inline, либо же реализацию сделать в заголовочном файле, то все компилится нормально.
Буду рад любым источникам, где про это можно почитать. |
|
Вернуться к началу |
|
|
kin
Зарегистрирован: 07.06.2006 Сообщения: 79
|
Добавлено: Пт Окт 31 2008 10:31 Заголовок сообщения: Re: проблема с inline-функциями |
|
|
goodmansem писал(а): | Появилась вот такая проблема: есть 3 файла..
[code]
//------------------------
inl.h
//------------------------
class A
{
public:
void init();
};
//------------------------
inl.cpp
//------------------------
#include "inl.h"
#include <stdio.h>
inline void A::init()
{
printf("init\n");
}
|
Попробуй так:
в inl.h: inline void init();
в inl.cpp: void A::init();
Точно не уверен, но скорее всего беда из-за этого |
|
Вернуться к началу |
|
|
критикан
Зарегистрирован: 18.02.2005 Сообщения: 247
|
Добавлено: Пт Окт 31 2008 11:37 Заголовок сообщения: и когда же Новодворская сядет вместо всех беременных зэчек? |
|
|
хорошо, что Кин не уверен, потому что причина в другом: компилятор старается подставить тело инлайн-функции вместо вызова. это удается, либо нет. если удается, то только когда, когда определение функции и место вызова находятся в одном файле, правда и это не является гарантией. если не удается, то функция считается обычной. что имеем у Гудмана? у него определение находится в одном файле (точнее в двух, которые во время компиляции склеиваются в один: -- inl.h+inl.cpp), а вызов происходит в другом файле (main.cpp). при этой ситуации происходит:
1. inl.h+inl.cpp компилируется нормально, при этом никакой исполняемый код не генерируется, так как компилятор помнит, что A::init() объявлена инлайновой, но никаких вызовов функции не наблюдает. а так как никаких конфликтов при попытке подстановок нет (так как самих вызовов нет), соответственно компилятор считает подстановку успешной и продолжает считать её инлайновой;
2. при компиляции inl.h+main.cpp в месте вызова a.init() компилятор, помня, что A::init() объявлена инлайновой, пытается найти в тексте inl.h+main.cpp тело функции A::init(), но не находит его и компилирует её как обычную, неинлайновую, функцию. то есть в этом месте пишется не фактическое тело функции (как должно быть при успешной подстановке инлайновых функций), а ее вызов
3. линкер при слиянии int.o+main.o пытается найти адрес A::init(), чтобы подставить его в место вызова a.init(), но такого адреса нет, так как - напомню - компилятор не сгенерировал код функции. естественно - undefined reference to `A::init(void)'
вывод: нужно, чтобы тело функции находилось в одном файле с вызовом. то есть объединить файлы inl.cpp и main.cpp в один
--------------------------------------
и когда же Новодворская сядет вместо всех беременных зэчек, а не только вместо беременной миллиардерши? |
|
Вернуться к началу |
|
|
Mytilus Galloprovincialis
Зарегистрирован: 30.08.2005 Сообщения: 358 Откуда: откуда все люди родятся
|
Добавлено: Ср Ноя 19 2008 02:46 Заголовок сообщения: |
|
|
Нет. Просто в объявлении метода тоже надо указть inline:
inline void init(); |
|
Вернуться к началу |
|
|
критикан
Зарегистрирован: 18.02.2005 Сообщения: 247
|
Добавлено: Чт Ноя 20 2008 14:26 Заголовок сообщения: первым пользователем бритвы Оккама был Прокруст |
|
|
Mytilus Galloprovincialis писал(а): | Нет. Просто в объявлении метода тоже надо указать inline:
inline void init(); |
не пойдёт. вот, что даёт гнусный, то есть gnu-шный, компилятор:
C:\...\ccIngaaa.o(.text+0x13):main.cpp: undefined reference to `A::init(void)'
-----------------------------------------------------------
первым пользователем бритвы Оккама был Прокруст |
|
Вернуться к началу |
|
|
Mytilus Galloprovincialis
Зарегистрирован: 30.08.2005 Сообщения: 358 Откуда: откуда все люди родятся
|
Добавлено: Чт Ноя 20 2008 15:22 Заголовок сообщения: |
|
|
Да? Сейчас у меня, увы, нет под рукой никакой среды разработки, но точно один из двух вариантов должен работать:
Код: | class A {public: inline void init();};
inline void A::init() {} | или Код: | class A {public: inline void init();};
void A::init() {} |
|
|
Вернуться к началу |
|
|
критикан
Зарегистрирован: 18.02.2005 Сообщения: 247
|
Добавлено: Пн Ноя 24 2008 13:20 Заголовок сообщения: будь проще -- и программа на C++ заработает |
|
|
Mytilus Galloprovincialis писал(а): | Да? Сейчас у меня, увы, нет под рукой никакой среды разработки, но точно один из двух вариантов должен работать {...} |
будут оба, но только если при компиляции в одном файле окажутся
Код: | class A {public: inline void init();};
inline void A::init() {}
A x; x.init (); |
см. сообщение от Пт Окт 31 2008 12:37
----------------------------------------------
будь проще -- и программа на C++ заработает |
|
Вернуться к началу |
|
|
Mytilus Galloprovincialis
Зарегистрирован: 30.08.2005 Сообщения: 358 Откуда: откуда все люди родятся
|
Добавлено: Пн Ноя 24 2008 21:21 Заголовок сообщения: |
|
|
Да, проверил - действительно так, как пишет критикан. |
|
Вернуться к началу |
|
|
|