Visualizzazione dei risultati da 1 a 5 su 5
  1. #1
    Utente di HTML.it L'avatar di edriv
    Registrato dal
    Oct 2004
    Messaggi
    367

    [C++] Problemi di linker

    Ho un progetto che si basa su diversi file sorgenti (.cpp e .h).
    All'inizio di ogni file ho messo le istruzioni al preprocessore che dovrebbero impedire errori di ridefinizione, esempio:
    codice:
    //Inizio del file:
    #ifndef _EXPRCLASS_MAIN_CPP_
    #define _EXPRCLASS_MAIN_CPP_
    // ... file
    
    // Fine del file:
    #endif // _EXPRCLASS_MAIN_CPP_
    Solo che il linker continua a darmi errori di ridefinizione sulle variabili pubbliche...
    Come è possibile? Sembra strano con queste precauzioni...

    dimenticavo, il compilatore è gcc su Dev-C++ (Addio VisualC++ )

  2. #2
    Utente di HTML.it L'avatar di anx721
    Registrato dal
    Apr 2003
    Messaggi
    2,352
    l'ifndef va messo nei file header; comunque posta il codice per se vuoi che scoviamo l'errore


    Sun Certified Java Programmer

    EUCIP Core Level Certified

    European Certification of Informatics Professionals

  3. #3
    Utente di HTML.it L'avatar di edriv
    Registrato dal
    Oct 2004
    Messaggi
    367
    Ho metto l'ifndef su tutto per escludere eventuali strani errori...

    Il file main.cpp contiene solo il main ed in seguito dovrebbe utilizzare la classe in Expr.h
    codice:
    #ifndef _EXPRCLASS_MAIN_CPP_
    #define _EXPRCLASS_MAIN_CPP_
    
    #include <iostream>
    #include "Expr.h"
    
    using namespace std;
    
    int main()
    {
    	system("PAUSE");
    	return 0;
    }
    
    #endif // _EXPRCLASS_MAIN_CPP_
    File Expr.h:
    codice:
    #ifndef _EXPR_H_
    #define _EXPR_H_
    
    /*
    Commento iniziale
    */
    
    #include <string>
    // Per i vettori di funzioni e variabili
    #include <vector>
    // Inseritori ed estrattori
    #include <iostream>
    // Per definire l'array di funzioni pubblico
    #include "ExprFunction.h"
    using namespace std;
    
    #define NUMBER double
    
    // Varie strutture utilizzate:
    enum en_expr_state
    {
    ...
    };
    
    enum expr_element_type
    {
    ...
    };
    
    enum expr_node_type
    {
    ...
    };
    
    class expr_element
    {
    ...
    };
    
    class expr_node
    {
    ...
    };
    
    class Expr
    {
    // privati
    public:
    // membri pubblici
    
    };
    
    // Questi qui danno problemi:
    
    // Vettore che contiene tutti i valori delle variabili
    char c;
    // Vettore che contiene tutte le strutture
    vector<ExprFunction> exprFunctions;
    
    #endif // _EXPR_H_
    Altri file sono ExprFunction.h , StdFunctions.h, ExprFunction.cpp (include il rispettivo header) ed Expr.cpp (include Expr.h)

    Se sposto quelle due variabili pubbliche in main va tutto bene, ma non mi va... e vorrei capire l'errore!
    Grazie dell'interesse

  4. #4
    Utente di HTML.it L'avatar di anx721
    Registrato dal
    Apr 2003
    Messaggi
    2,352
    Con

    char c;


    definisci una variabile c: incontrando quella dichiarazione il compilatore riserverà una locazione di memoria associata al nome c. Se includi quel file header in piu file .cpp, quella definizione sarà ripetuta per ognuno di questi file, cosi si hanno multiple definizioni della stessa variabile e a tempo di esecuzione non si saprebbe quale considerare.

    Per avere le idee piu chiare bisogna distinguere tra dichiarazione e definizione; con la dichiarazione di una variabile o di una funzione dici semplicemente al compilatore che quella variabile o quella funzione esiste da qualke parte; ciò nn comporta l'allocazione di zone di memoria per la variabile o la funzione; con la definizione invece crei effettivamente la variabile o la funzione e ne allochi la memoria.

    In un file header metti le dichiarazioni di varie funzioni, senza mettere il corpo delle funzioni: ovvero non definisci le funzioni, solo le dichiari, cosi puoi mettere la dichiarazione di una stessa funzione piu volte in vari files da linkare insieme. D'altro canto nn puoi definire piu volte la stessa funzione, cioè dare il copro della funzione piu volte, se no hai un conflitto.

    La stessa regola vale per le variabili: nel file header devi semplicemente metterci la dichiarazione, ma non definire la variabile; la dichiarazione servirà solo a dire che da qualke altra parte quella variabile sarà definita. Mentre per dichiarare senza definire una funzione usi il suo prototipo senza mettere il corpo della funzione, per dichiarare senza definire una variabile si usa la parola chiave extern:

    extern char c;

    con questa dichiarazione il compilatore mette nella sua tabella di dati il nome della variabile c per ricordarsi che da qualke parte sarà definita, ma non alloca memoria per essa. Quindi nei tuoi files header anzicche mettere la definiziopne delle varibili, devi metterci solo la dichiarazione, che si ottiene con la parola chiave extern.

    Quelle stesse variabili devono poi esere definite (senza extern) in uno (e solo uno) file cpp, come ad esempio il file del main.

    Definizione e dichiarazione sono concetti ben sottolineati da uno dei piu diffusi libri sul c++, ovvero il thinking in c++ di bruce eckel, che puoi scaricare liberamente dalla rete:

    It’s important to understand the difference between declarations and definitions because these terms will be used precisely throughout the book. Essentially all C and C++ programs require declarations. Before you can write your first program, you need to understand the proper way to write a declaration.


    A declaration introduces a name – an identifier – to the compiler. It tells the compiler “This function or this variable exists somewhere, and here is what it should look like.” A definition, on the other hand, says: “Make this variable here” or “Make this function here.” It allocates storage for the name. This meaning works whether you’re talking about a variable or a function; in either case, at the point of definition the compiler allocates storage. For a variable, the compiler determines how big that variable is and causes space to be generated in memory to hold the data for that variable. For a function, the compiler generates code, which ends up occupying storage in memory.


    You can declare a variable or a function in many different places, but there must be only one definition in C and C++ (this is sometimes called the ODR: one-definition rule). When the linker is uniting all the object modules, it will usually complain if it finds more than one definition for the same function or variable.

    Inoltre elimina la direttiva ifndef dai file .cpp perke non si mette; quella direttiva serve solo a nn includere piu bvolte lo stesso file in un altro e visto che non includi file cpp nn serve, anzi potrebbe nasconderti dei bug se per caso fai delle inclusioni errate.


    Sun Certified Java Programmer

    EUCIP Core Level Certified

    European Certification of Informatics Professionals

  5. #5
    Utente di HTML.it L'avatar di edriv
    Registrato dal
    Oct 2004
    Messaggi
    367
    Ho fatto ancore confusione tra file .h e .cpp

    Comunque ho risolto semplicemente mettendole come membri statici della classe.

    Grazie

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.