Ir para conteúdo
Fórum Script Brasil
  • 0

uso de variável extern em C++


Castro

Pergunta

:rolleyes:

Considere o projeto abaixo:

Criei um projeto chamado global, que contém dois arquivos:

externa.h

extern const double PI =3.1416; // cria uma constante global externa
E um arquivo principal.cpp
#include <iostream>
#include "externa.h"
using namespace std;

int main()
{
    cout << PI;
    system("PAUSE");
    return 0;
}

para usar a constante global, entretanto, está ocorrendo os seguinte erros:

/Dev-Cpp/Templates/principal.cpp D:\Sobre_C++\ProgC++funcionando\C externa.h: No such file or directory.

C:\Dev-Cpp\Templates\principal.cpp In function `int main()':

7 C:\Dev-Cpp\Templates\principal.cpp `PI' undeclared (first use this function)

(Each undeclared identifier is reported only once for each function it appears in.)

D:\Sobre_C++\ProgC++funcionando\Makefile.win [build Error][C:/Dev-Cpp/Templates/principal.o] Error 1

O que está errado ? estou colocando todos os arquivos no mesmo diretório.

Obrigado

Link para o comentário
Compartilhar em outros sites

10 respostass a esta questão

Posts Recomendados

  • 0

o dev c++ so vai encontar o include se tiver na pasta include dentro da pasta do dev c++ mesmo.

se a pasta tiver em outro diretorio, você vai ter q passar o caminho todo, exemplo:

#include "C:\caminho\externa.h"

ou então você entra em menu Tools -> Compiler Options -> aba Directories -> aba C Includes ou C++ Includes e adiciona la o caminho. ai você podera so por o nome do arquivo no codigo, sem precisar do caminho.

ou se você tiver mexendo num projeto .dev, você entra em menu Project -> Project Options -> aba Directories -> aba Include Directories e adiciona la o caminho. ai ele so valera pra esse seu projeto.

Link para o comentário
Compartilhar em outros sites

  • 0

:rolleyes:

Vou fazer o teste. Mas achei estranho, pois sempre li, que bastava colocar os arquivos .h e os arquivos .cpp no mesmo diretório. Por que isso ?

Certa vez, criei dois arquivos .cpp, onde num coloquei a chamada de iostream, namespace std;, a fumção main() com as chamadas das funções contidas no outro arquivo .cpp, e deu tudo certo. Não deu erro, não precisei nem colocar o protótipo da função num arquivo .h e as funções definidas pelo unuário num arquivo separado do arquivo que contém a função main(), como em programas C.

Poderiam explicar o porquê disso ? o procedimento de incluir todo o caminho é válido para todo compilador ou só para o DEV-C++ ?

Obrigado

Link para o comentário
Compartilhar em outros sites

  • 0
Mas achei estranho, pois sempre li, que bastava colocar os arquivos .h e os arquivos .cpp no mesmo diretório.

O diretório do projeto está (ou deveria estar) na busca default do compilador. Ele é esperto o suficiente pra saber isso. Realmente. Em linha de comando garanto que não dá esse problema. Talvez a IDE (que não uso muito) pode não ter essa "esperteza" toda e, como o compilador é invocado indiretamente, ela pode não estar passando pra ele o diretório do fonte para uma busca pelo header do projeto. Se ela fizer isso, vai usar o switch que indiquei na minha mensagem anterior.

Certa vez, criei dois arquivos .cpp, onde num coloquei a chamada de iostream, namespace std;, a fumção main() com as chamadas das funções contidas no outro arquivo .cpp, e deu tudo certo.

Alguns headers já são incluídos por outros headers e por isso não precisam ser explicitamente incluídos no seu fonte. Taí o "mistério". :)

o procedimento de incluir todo o caminho é válido para todo compilador ou só para o DEV-C++ ?

Não que seja comum a todo compilador, mas todo compilador vai aceitar. O ideal é não informar path de header no seu fonte. Se os arquivos mudarem de lugar e você tiver dezenas de fontes, já viu o trabalho que vai dar pra atualizar tudo. Se puder, apenas informe o compilador qual diretório ele deve procurar.

Link para o comentário
Compartilhar em outros sites

  • 0

bom, pra dizer a verdade, apesar de eu já ter feito isso antes, esqueci quando escrevi o outro post, mas se você entrar la no Compiler Options como eu disse, e adicionar o caminho . (isso mesmo, digite um ponto e clique em Add), ele vai sempre procurar o header no proprio diretorio pra todos os arquivos.

Link para o comentário
Compartilhar em outros sites

  • 0

:rolleyes:

Fiz o teste de duas formas diferentes.

1- Só indiquei o caminho no #include. Não deu certo;

2- Considerei como projeto, e segui as orientações para projeto dev no post 2, deixei o caminho no #include. Não deu certo,

3- Tirei o caminho do #include, e deixei o caminho nas opções de projeto, não deu certo.

4- Tirei o caminho de opções de projeto e voltei a colocar no #include.

O que me chamou a atenção, é que os erros mostrados indicam outros problemas referentes ao arquivo .h. Por isso, vou postar o projeto com os erros para vocês verem.Eu realmente uso a IDE para Windows, e isso deve gerar algumas dificuldades.

Por falar nisso, o que vocês chamam de:

switch -I na linha de comando
Eu já tive que usar parâmetros para incluir pacotes no DEV-C++, mas..

Eis o projeto

Arquivo cpp

#include "D:\Sobre_C++\ProgC++funcionando\externa.h"
#include <iostream>
using namespace std;

int main()
{
    cout << PI;
    system("PAUSE");
    return 0;
}
Arquivo .h
extern const double PI 3.1416;  // cria uma contante global externa

/* O expeciificador extern permite que uma variiável seja conhecida
por outro módulo, mas não cria na realidade aquela variável. Em outras
palavras, extern que o compilador saiba quais são os tipos e nomes para
estas variáveis globais sem na realidade crirar armazenazem para elas
novamente. Qundo o linker liga os dois módulos todas as referências
são resolvidas*/

Erros:

1 C:\Dev-Cpp\Templates\principal.cpp In file included from C:/Dev-Cpp/Templates/principal.cpp

1 D:\Sobre_C++\ProgC++funcionando\externa.h expected init-declarator before numeric constant

1 D:\Sobre_C++\ProgC++funcionando\externa.h expected `,' or `;' before numeric constant

C:\Dev-Cpp\Templates\principal.cpp In function `int main()':

7 C:\Dev-Cpp\Templates\principal.cpp `PI' undeclared (first use this function)

(Each undeclared identifier is reported only once for each function it appears in.)

D:\Sobre_C++\ProgC++funcionando\Makefile.win [build Error] [C:/Dev-Cpp/Templates/principal.o] Error 1

Obrigado

Editado por Castro
Link para o comentário
Compartilhar em outros sites

  • 0

o problema é q ta faltando um igual aqui:

extern const double PI 3.1416;
tem q ser assim:
extern const double PI = 3.1416;

o include ele ta achando certo.

quanto aquela historia dos diretorios e etc, acho q a melhor opcao é essa daqui mesmo ó:

bom, pra dizer a verdade, apesar de eu já ter feito isso antes, esqueci quando escrevi o outro post, mas se você entrar la no Compiler Options como eu disse, e adicionar o caminho . (isso mesmo, digite um ponto e clique em Add), ele vai sempre procurar o header no proprio diretorio pra todos os arquivos.

assim, não importa o arquivo ou projeto q você teja usando, ele sempre vai procurar o include no mesmo diretorio.

Link para o comentário
Compartilhar em outros sites

  • 0

:D

Ok. Deu certo. Mas existe aplicação em C++ para extern ? em C, era um recurso para se ter variável global. O comentário feito está certo ?

Existe uma outra aplicação para extern, que diz:

Avariação em extern fornece uma especificação de link que é uma instrução para o compilador sobre como uma função deve ser tratada pelo linker. Por default, as funções são lincadas como funções de C++, mas uma especificação de link permite que você ligue uma função para um tipo diferente de linguagem, A forma geral de um especificador de link

extern"linguagem" funtion-prototype - Schildt

extern "C" void myCfunc();

No exmplo e citação acima, fala-se em tratamento diferenciado de função.Pelo que entendi, permite a ultilização de funções criadas em outras linguagens no C++. Correto ? caso tenha entendido certo, como seria isso ? no casso de C para C++ não vejo vantagem, como mostrado. Poderia comentar ?

Obrigado

Editado por Castro
Link para o comentário
Compartilhar em outros sites

  • 0

Talvez o Schildt não comente no livro, mas há alguns outros aspectos importantes a considerar. C++, como OOP, possui um recurso chamado de overloading; sobrecarga de funções, onde uma mesma função pode aceitar argumentos diferentes e manter o mesmo nome. Mas se duas funções compartilham do mesmo nome, como o compilador sabe qual função usar? A própria parametrização é um recurso que o compilador usa. Mas não é só isso. Há também o que se chama de name mangling, que é uma técnica que cria para a função um nome diferente do "real", o que constitui uma "assinatura" para cada função. C não tem isso, até porque nem precisa. Mas quando você faz uso de uma função C (uma LIB especial, por exemplo) em código C++, você precisa avisar o compilador que para aquela função C não deverá ser utilizado name mangling. Daí a necessidade do "extern "C" .... Sem isso o compilador vai mandar o linker procurar por um nome de símbolo que não existe. É erro na certa. Note também que uma função C, nessas condições, não pode ser sobrecarregada, já que para este recurso o uso do name mangling é mandatório.

Aliás, repare que devido ao fato do name mangling produzir um objeto com nome de símbolo bem diferente do nome "real" da função, fica torna impossível um código C usar código C++ de uma biblioteca de funções. A não ser, claro, que algum compilador tenha algum switch especial que permita ao programador desligar o name mangling ao criar uma biblioteca para uso externo. Não conheço nenhum que tenha, e duvido que exista. Estou só "aventando" uma possibilidade. :)

PS: Mais detalhes sobre name mangling podem ser obtidas pelo Google. Mas é coisa simples e fácil de entender.

Link para o comentário
Compartilhar em outros sites

Participe da discussão

Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,3k
    • Posts
      652,3k
×
×
  • Criar Novo...