Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
Архив форумов ЦИТФорума
Море(!) вопросов - Море(!) ответов
 
 FAQFAQ   ПоискПоиск   ПользователиПользователи   ГруппыГруппы   РегистрацияРегистрация 
 ПрофильПрофиль   Войти и проверить личные сообщенияВойти и проверить личные сообщения   ВходВход 
Как правильно задавать вопросы

проблема с inline-функциями

 
Перейти:  
Этот форум закрыт, вы не можете писать новые сообщения и редактировать старые.   Эта тема закрыта, вы не можете писать ответы и редактировать сообщения.    Список форумов Архив форумов ЦИТФорума -> Программирование
Предыдущая тема :: Следующая тема  
Автор Сообщение
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    Заголовок сообщения: Ответить с цитатой

Да, проверил - действительно так, как пишет критикан.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение
Показать сообщения:   
Этот форум закрыт, вы не можете писать новые сообщения и редактировать старые.   Эта тема закрыта, вы не можете писать ответы и редактировать сообщения.    Список форумов Архив форумов ЦИТФорума -> Программирование Часовой пояс: GMT + 3
Страница 1 из 1

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах


Powered by phpBB © 2001, 2002 phpBB Group
Русская поддержка phpBB

 

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 495 6608306, ICQ 232284597
Пресс-релизы — pr@citforum.ru
Послать комментарий
Информация для авторов
This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2006 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...