Ошибка компилятора C ++: ld: символы не найдены для функции-члена, на которую ссылается _main - PullRequest
1 голос
/ 09 ноября 2010

Я очень смущен ошибкой компилятора.Мой код полностью работал 4-5 часов назад;единственно возможная контрольная точка на этом пути не дала никаких подсказок (т.е. я не смог заставить ошибку исчезнуть на одном промежуточном этапе).Я не понимаю, как ошибка компилятора может быть связана с какими-либо внесенными мною изменениями.

Компиляция с g++ -O3 -o a.out -I /Applications/boost_1_42_0/ Host.cpp Simulation.cpp main.cpp Rdraws.cpp SimPars.cpp

появляется следующая ошибка

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

Я создаю и манипулирую Simulation объектами в main.Единственными моими изменениями в коде были (1) создание новой функции-члена Simulation::runTestEpidSim(), которая вызывается в main, и (2) написание некоторых новых глобальных функций обработки ввода / вывода, которые я с тех пор развернули вставлен непосредственно в main для отладки происходящего.

Я не менял никаких файлов cpp, включает в себя, файлы заголовков, библиотеки или команды компилятора.

Я не являюсьпрофессиональный программистКак профессионалы пойдут на отладку такого рода проблем?

Не знаю, как лучше всего вырезать и вставить мой код, но вот выдержка -

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;
}

, которую я ранее выполнял runEpidSim() без проблем.

Обновление У меня есть полный код для реализации Simulation::runTestEpidSim() - я понятия не имею, как лучше представить это!

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 );
}

Ответы [ 4 ]

5 голосов
/ 09 ноября 2010

Как профессионалы пойдут в устранении проблемы такого рода?

Вы должны начать с сообщения об ошибке:

Undefined symbols:"Simulation::runTestEpidSim()"

Вы добавили прототипдля runTestEpidSim, но вы не показали определение этой функции (предположительно, это должно быть в Simulation.cpp)

Вот что я бы искал, чтобы начать ...

  • Вы уже определили это?
  • Вы определили его как члена класса Simulation?
  • Вы определили его с точно такими же параметрами?
  • Вы определили его с точно таким же типом возвращаемого значения?
  • Это определение случайно закомментировано или # ifdef'd out?

Обновление Спасибо за размещение определения.То, что вы опубликовали, выглядит отлично и проходит первые четыре теста выше - но вы можете видеть, как несовпадающий #ifdef DEBUG может испортить вам жизнь ...

Кроме того ...

  • Вы действительно скомпилировали и связали файл, содержащий определение?
1 голос
/ 09 ноября 2010

Похоже, вы объявили функцию, но не реализовали ее

1 голос
/ 09 ноября 2010

Где вы определили runTestEpidSim? Вы определили это с правильной подписью в том же файле, содержащем main? Если он определен в каком-то другом файле: включили ли вы этот файл в процесс сборки?

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

Код, который вы дали, содержит только объявление, так где же определение?

1 голос
/ 09 ноября 2010

В сообщении об ошибке компоновщика говорится, что у вас нет определения для запуска * Test * EpidSim, который вам необходим при вызове этой функции внутри main. Ваше описание соответствует этой проблеме: вы объявили этот новый метод, но нигде не реализовали его. Вам необходимо предоставить фактический исходный код этой тестовой функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...