Linux slogan
Visite também: BR-Linux.org · Dicas-L · NoticiasLinux · SoftwareLivre.org · UnderLinux · BestLinux
» Screenshot
Linux: Fluxbox
Por xxtiagoxx



» Login
Login:
Senha:

Se você ainda não possui uma conta, clique aqui.

Esqueci minha senha

» Wallpaper
Linux: FrozenTux
Por atilazip

Comunidades

Problema função inline

Linux user
leandroparker

(usa Slackware)
Enviado em 27/08/2008 - 18:29h:
Problema função inline

Saudações!

Estudo C++ e estou com dificuldades para resolver um erro numa função inline

Segue um exemplo:

//Arquivo teste.h
class teste
{
private:
int a;

public:
inline void altera(int x);
}

//Arquivo teste.cpp
#include"teste.h"

inline teste::altera(int x)
{
a = x;
}

//Arquivo exec.cpp
#include"teste.h"

int main()
{
teste var;
var.altera(10);

return 0;
}

Quando compilo e executo gera o seguinte erro:

/caminho/exec.cpp:6: undefined reference to `teste::altera(int)'
 

  
Linux user
pferrarezi

(usa Fedora)
Enviado em 27/08/2008 - 18:37h:


vc tem q definir o método ...
 

Linux user
slack felix

(usa Slackware)
Enviado em 27/08/2008 - 18:54h:


Olá,

Se não me engano com as funções inline ocorre o mesmo que com os gabaritos de funções. As declaroções e as definições devem ficar no mesmo arquivo, ou seja, você tem que ter algo como:

//Arquivo teste.h
class teste
{
private:
int a;

public:
inline void altera(int x);
}

inline teste::altera(int x)
{
a = x;
}

//Arquivo exec.cpp
#include"teste.h"

int main()
{
teste var;
var.altera(10);

return 0;
}

Dá uma olhada se é isso mesmo.
 

Linux user
mslomp

(usa Slackware)
Enviado em 27/08/2008 - 23:11h:


o amigo aí de cima disse certo. funções inline devem ser prototipadas e definidas em um mesmo objeto, embora C89 defina o uso de "extern inline". por serem as funções inline expandidas ainda em passagens de compilação, nao podem (nem devem) ser referências externas. é importante observar que o gcc (-O2+ ativando -finline-small-functions) pode associar automaticamente fragmentos comuns de código e expandi-las ao longo do código fonte como se fossem funções inline, embora você não as tenha explicitado como tais.
 

Linux user
gjr_rj

(usa Debian)
Enviado em 28/08/2008 - 02:12h:


Dá forma que está vai dar erro mesmo, pois falta o ";" depois da definição da classe, isso independente da forma como você usa.

Pode separar sim as definições das implementação, não tem problema, porém vou começar do início.

Para você declarar um método como inline, basta a implementação está dentro do escopo da classe. E caso não queira, implemente fora (sem a definição de inline)

//Arquivo teste.h EXEMPLO 1
class teste
{
private:
int a;

public:
/* alterar é inline pois sua implementação está dentro do escopo da classe */
void altera(int x)
{
a = x;
}
};

//Arquivo teste.h EXEMPLO 2
class teste
{
private:
int a;

public:
void altera(int x);
};
/* Implementação fora, não é inline */
void teste::altera(int x)
{
a = x;
}


Porém se quiser fazer a implementação fora e deseja que seja inline, basta usar a definição inline na implementação do método.

//Arquivo teste.h EXEMPLO 3
class teste
{
private:
int a;

public:
/* não é necessário inline aqui, tanto faz inline void altera ... quanto apenas void altera ... */
void altera(int x);
};

//aqui é necessário o inline
inline void teste::altera(int x)
{
a = x;
}

Em ambos os casos, o include no arquivo principal será da lib teste.h

//Arquivo exec.cpp
/*****************/
#include "teste.h"
/*****************/

int main(void)
{
teste var;
var.altera(10);

return 0;
}

Porém você quer em arquivos separados. Não lembro se neste caso é necessário ou não o uso do inline na declaração do método, estou quase certo que não precisa, mas coloquei com o inline no exemplo só por garantia. Então ficaria assim:

//Arquivo teste.h EXEMPLO 4
class teste
{
private:
int a;

public:
/* não lembro se é necessário ou não o inline neste caso */
inline void altera(int x);
}; // <-- olha o ponto e vírgula.


//Arquivo teste.cpp
/*****************/
#include "teste.h"
/*****************/

//aqui é necessário o inline
inline void teste::altera(int x)
{
a = x;
}

Neste caso o arquivo principal deve dar um include no CPP

//Arquivo exec.cpp
/*****************/
#include "teste.cpp"
/*****************/

int main(void)
{
teste var;
var.altera(10);

return 0;
}

Não sei que compilador está usando, mas eu gosto do gcc.

Espero ter ajudado.
 

Linux user
leandroparker

(usa Slackware)
Enviado em 28/08/2008 - 12:28h:


Valeu pela dica.

Despulpe pela lapso, mas o arquivo .h e ; eu esquici na hora de redigir a pergunta, mas continua dando erro, já tentei em vários compiladores e o erro é o mesmo.
 

Linux user
mslomp

(usa Slackware)
Enviado em 28/08/2008 - 13:17h:


o problema inicial (undefined reference) está relacionado ao processo de linkagem e geração do binário executável. como mencionei anteriormente, você não deve referenciar funções inline a partir de objetos externos (me refiro a código-objeto, nao a arquivos fonte externos). você pode utilizar o método descrito pelo colega acima para manter a definição separada da prototipagem e utilizar o #include <teste.cpp>, porém isso causará impacto na legibilidade (não do código, mas da estrutura), e alguma possível confusão no makefile (caso utilize).

mantendo-se tanto a definição quanto o protótipo no header, teremos:

//Arquivo teste.h
class teste
{
private:
int a;

public:
inline void altera(int);
};

inline void teste::altera(int x)
{
a = x;
}

//=======================//

//Arquivo exec.cpp
#include"teste.h"

int main()
{
teste var;
var.altera(10);

return 0;
}

//===================//

compilando:
# gcc exec.cpp -o teste

o código acima deverá compilar sem problemas nem warnings em qualquer versão do gcc.
 

Linux user
leandroparker

(usa Slackware)
Enviado em 28/08/2008 - 14:54h:


Interessante é que quando eu retiro o inline dos arquivos compila normalmente.
 

Linux user
leandroparker

(usa Slackware)
Enviado em 28/08/2008 - 15:00h:


Eu fiz um teste sem o inline, mas comentando a função altera no módulo teste.cpp e ele gerou o mesmo erro, "undefined reference", é como se com o inline ele não encontrasse a função no módulo teste.cpp.
 

Linux user
gjr_rj

(usa Debian)
Enviado em 28/08/2008 - 19:30h:


Se você tirar os inline's compila ?!

Como você está compilando ?

O que seria normal, no meu ponto de vista, é ele apresentar o mesmo erro tanto com o cpp ou sem o cpp, com inline ou sem inline.

Pois acredito que o teste.cpp não faz diferença ?
 

Linux user
leandroparker

(usa Slackware)
Enviado em 29/08/2008 - 10:02h:


Então, eu estou compilando em várias IDEs: NetBeans, eclipse, DevCPP e em modo texto com o gcc, todos apresentam o mesmo resultado, basta tirar o inline para funcionar normalmente, sinceramente não consegui entender.
 

Linux user
gjr_rj

(usa Debian)
Enviado em 29/08/2008 - 10:12h:


copiei seu exemplo e tentei compilar com o gcc, porém o seu exemplo apresenta uma mensagem completamente diferente.

/tmp/ccUCzmiB.o: In function `main':
exec.cpp:(.text+0x20): undefined reference to `teste::altera(int)'
/tmp/ccUCzmiB.o:(.eh_frame+0x11): undefined reference to `__gxx_personality_v0'
collect2: ld returned 1 exit status

independente se está com inline ou não
 

  
<< Anterior Próxima >>
Contribuir com: [ Artigo | Conf | Dica | Pergunta | Script | Screenshot | Simulado | Wallpaper ]
Responsável pelo site: Fábio Berbert de Paula - Copyleft© 2002-2008 Viva o Linux.com.br

Viva o Linux

A maior comunidade Linux do Brasil! Artigos, dicas, tutoriais, fórum, scripts e muito mais. Ideal para quem busca auto-ajuda em Linux.