I’m very confused by a compiler error. My code was thoroughly working 4-5 h ago; the only feasible checkpoint along the way hasn’t yielded any clues (i.e., I have not been able to get the error to disappear at one intermediate step). I don’t see how the compiler error could be related to any of the changes I have made.
Compiling with
g++ -O3 -o a.out -I /Applications/boost_1_42_0/ Host.cpp Simulation.cpp main.cpp Rdraws.cpp SimPars.cpp
the following error appears
Undefined symbols:
"Simulation::runTestEpidSim()", referenced from:
_main in ccmcSY5M.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
I create and manipulate Simulation objects in main. My only changes to the code were (1) to create a new member function, Simulation::runTestEpidSim(), which is called in main, and (2) to write some new global input/output processing functions, which I’ve since unwrapped and inserted directly into main in order to debug what’s going on.
I have not changed any cpp files, includes, header files, libraries, or compiler commands.
I’m not a professional programmer. How would the pros go about debugging this kind of problem?
Not sure how best to cut and paste my code, but here’s an 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;
}
I had previously been executing runEpidSim() with no problem.
Update
I have the full code for the implementation of Simulation::runTestEpidSim()–I have no idea how best to present this!
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 );
}
You should start with the error message:
You’ve added a prototype for runTestEpidSim, but you haven’t shown the definition of this function (presumably it should be in Simulation.cpp)
Here’s what I’d look for, to start…
Update
Thanks for posting the definition. What you’ve posted looks fine, and passes the first four tests above – but you can see how a mismatched #ifdef DEBUG could mess things up for you…
In addition…