2010-11-09 23 views
1

Je suis très confus par une erreur de compilation. Mon code fonctionnait à fond il y a 4-5 heures; le seul point de contrôle réalisable en cours de route n'a fourni aucun indice (c'est-à-dire que je n'ai pas réussi à faire disparaître l'erreur à une étape intermédiaire). Je ne vois pas comment l'erreur du compilateur pourrait être liée à l'un des changements que j'ai faits.Erreur de compilation C++: ld: symbole (s) introuvable pour la fonction membre référencée à partir de _main

Compiler avec g++ -O3 -o a.out -I /Applications/boost_1_42_0/ Host.cpp Simulation.cpp main.cpp Rdraws.cpp SimPars.cpp

l'erreur suivante apparaît

Undefined symbols: 
    "Simulation::runTestEpidSim()", referenced from: 
     _main in ccmcSY5M.o 
ld: symbol(s) not found 
collect2: ld returned 1 exit status 

créer et manipuler des objets dans Simulationmain. Mes seuls changements au code étaient (1) pour créer une nouvelle fonction membre, Simulation::runTestEpidSim(), qui est appelée dans main, et (2) pour écrire de nouvelles fonctions globales de traitement d'entrée/sortie, que j'ai depuis déballé et inséré directement dans main afin de déboguer ce qui se passe.

Je n'ai pas modifié les fichiers cpp, inclus, les fichiers d'en-tête, les bibliothèques ou les commandes du compilateur.

Je ne suis pas un programmeur professionnel. Comment les pros vont-ils débugger ce genre de problème?

Je ne sais pas la meilleure façon de couper et coller mon code, mais voici un excerpt--

class Simulation 
{ 
public: 
    Simulation(int trt, int sid, SimPars * spPtr ); 
    ~Simulation(); 

    // MEMBER FUNCTION PROTOTYPES 
    void runDemSim(void); 
    void runEpidSim(void); 
    double runTestEpidSim(void); 
... 
} 

int main() { 
for (int trt = 0; trt < NUM_TREATMENTS; trt++) { 

    double treatment = TREATMENTS[ trt ]; 
    .... 
    cout << "Treatment #" << trt + 1 << " of " << NUM_TREATMENTS << ":" << endl; 
    int matchAttempts = 0; 
    double prevError = 1.0 + PREV_ERROR_THOLD; 
    double thisBeta = 0.0; 
    while (matchAttempts < MAX_MATCH_ATTEMPTS && prevError > PREV_ERROR_THOLD) { 
    cout << " Attempt #" << matchAttempts + 1; 
    SimPars thesePars; 
    SimPars * spPtr = &thesePars; 
    Simulation thisSim(trt, 1, spPtr); 
    thisSim.runDemSim(); 
    prevError = thisSim.runTestEpidSim() - TARGET_PREV; 
    cout << ", error=" << prevError << endl; 
    if (prevError > PREV_ERROR_THOLD) { 
    .... 

return 0; 
} 

J'avais déjà été exécutais runEpidSim() sans problème.

Mise à jour Je le code complet pour la mise en œuvre de Simulation::runTestEpidSim() -I ont aucune idée de la meilleure façon de présenter cela!

double Simulation::runTestEpidSim(void) { 
    if (allHosts.size() == 0) { 
    cerr << "No hosts remaining for epidemiological simulation. Cancelling." << endl; 
    assert(false); 
    } 
    cout << " Entering test simulation at t=" << demComplete << "." << endl; 
    double percentDone = 0.0; 

    // Initialize host population with infections 
    demOutputStrobe = t; 
    epidOutputStrobe = t; 
    seedInfections(); 
    EventPQ::iterator eventIter = currentEvents.begin(); 
    double nextTimeStep = t + EPID_DELTA_T; 
    double prevalences[ NUM_TEST_SAMPLES ]; // holds prevalences at strobing periods 
    for (int p = 0; p < NUM_TEST_SAMPLES; p++) { 
    prevalences[ p ] = 0.0; 
    } 
    double prevYear = DEM_SIM_LENGTH + TEST_EPID_SIM_LENGTH - NUM_TEST_SAMPLES; // first simulation year to start sampling 
    int prevSamples = 0; 

    while (t < TEST_EPID_SIM_LENGTH + demComplete) 
    { 

#ifdef DEBUG 
     cout << "time step = " << t << " (" << allHosts.size() << " hosts; " << currentEvents.size() << " events queued)" << endl; 
     assert(currentEvents.size()>0); 
#endif 

     // Calculate new infections for every host and add events to stack 
#ifdef DEBUG 
     cout << "Adding infections for this time step: " << endl; 
#endif 
     calcSI(); 
     eventIter = currentEvents.begin(); 

#ifdef DEBUG 
     cout << "Executing events off stack (currentEvents.size()=" << currentEvents.size() << "): " << endl; 
#endif  

     while ((*eventIter).time < nextTimeStep) { 

    while (demOutputStrobe < t) { 
     writeDemOutput(); 
     demOutputStrobe += STROBE_DEM; 
    } 
    while (epidOutputStrobe < t) { 
     writeEpidOutput(); 
     epidOutputStrobe += STROBE_EPID; 
    } 
    if (prevYear < t) { 
     prevalences[ prevSample ] = calcPrev(); 
     cout << "\tOutputting prevalence sample #" << prevSamples+1 << "; prevalence under 5 is " << prevalences[ prevSample ] << endl; 
     prevSample++; 
    } 
     while (percentDone/100.0 < (t - demComplete)/EPID_SIM_LENGTH ) { 
     cout << "\t" << percentDone << "% of this test component complete." << endl; 
     percentDone += PROGRESS_INTERVAL; 
     } 

    // Execute events off stack 
    Event thisEvent = *eventIter; 
#ifdef DEBUG 
    assert(thisEvent.time >= t); 
    if (thisEvent.time < t) { 
     cout << "Trying to execute event scheduled for time " << thisEvent.time << ", though sim time is " << t << endl; 
     assert(thisEvent.time >= t); 
    } 
#endif 
    t = thisEvent.time; 


#ifdef DEBUG 
    cout << "\tt=" << t << endl; 
    // cout << "\tAbout to execute event ID " << (*eventIter).eventID << " at time " << (*eventIter).time << " for host ID " << (*eventIter).hostID << endl; 
    cout << "\tAbout to execute event ID " << thisEvent.eventID << " at time " << thisEvent.time << " for host ID " << thisEvent.hostID << endl; 
#endif 
    executeEvent(thisEvent); 
    eventCtr++; 
    currentEvents.erase(eventIter); // Check that if event added to top of currentEvents, will not invalidate itr 
    eventIter = currentEvents.begin(); 

#ifdef DEBUG 
    cout << "\tcurrentEvents.size() after pop is " << currentEvents.size() << endl; 
#endif 

     } 

     t = nextTimeStep; 
     nextTimeStep += EPID_DELTA_T; 
    } 

    double meanPrev = 0.0; 
    double sumPrev = 0.0; 
    int totSamples = 0; 
    for ( int p = 0; p < NUM_TEST_SAMPLES; p++) { 
    if (prevalences[ p ] > 0) { // in cae 
     sumPrev += prevalences[ p ]; 
     totSamples++; 
    } 
    } 
    cout << "Counted " << totSamples << " total prevalence samples." << endl; 
    meanPrev = sumPrev/(double)totSamples; 
    return(meanPrev); 
} 
+1

Où sont les implémentations (ou les corps) des méthodes de Simulation? –

Répondre

5

How would the pros go about debugging this kind of problem?

Vous devriez commencer par le message d'erreur:

Undefined symbols:"Simulation::runTestEpidSim()" 

vous avez ajouté un prototype pour runTestEpidSim, mais vous n'avez pas montré la définition de cette fonction (on peut supposer qu'il devrait être dans la simulation.cpp)

Voici ce que je cherche, pour commencer ...

  • Avez-vous défini du tout?
  • L'avez-vous défini en tant que membre de la classe Simulation?
  • L'avez-vous défini avec exactement les mêmes paramètres?
  • L'avez-vous défini avec exactement le même type de retour?
  • La définition est-elle accidentellement commentée ou # ifdef'd out?

Mise à jour Merci pour l'affichage de la définition. Qu'est-ce que vous avez posté l'air bien, et passe les quatre premiers essais ci-dessus - mais vous pouvez voir comment un DEBUG #ifdef pourrait ne correspondent pas gâcher les choses pour vous ...

En plus ...

  • Avez-vous réellement compilé et lié avec le fichier contenant la définition?
+1

Suspendu de ma tête dans la honte - Je pensais avoir vérifié cela, mais j'avais effectivement # ifdef'ed il. Merci de décrire comment vous aborderiez le problème. J'accepterai votre réponse dès que l'heure me le permettra. – Sarah

+0

+1 pour le "# ifdef" accidentel. N'a même pas traversé mon esprit une fois, et semble avoir été la bonne solution. – Dirk

1

Le message d'erreur linker dit que vous ne disposez pas d'une définition pour l'exécution * test * EpidSim, dont vous avez besoin que vous appelez cette fonction à l'intérieur principale. Votre description correspond à ce problème: vous avez déclaré cette nouvelle méthode, mais vous ne l'avez pas implémentée nulle part. Vous devez fournir le code source réel de cette fonction de test.

1

On dirait que vous avez déclaré la fonction mais pas mise en œuvre

1

Où avez-vous définir le runTestEpidSim? L'avez-vous défini avec la bonne signature dans le même fichier contenant main? Si elle est définie dans un autre fichier: avez-vous inclus ce fichier dans le processus de construction?

double 
Simulation::runTestEpidSim(void) 
{ 
    ... 
} 

Le code que vous avez donné ne contient que la déclaration, alors où est la définition?