Many undefined references

So I am getting undefined references

timer.H

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#ifndef _timer_H_                   // include file only once
#define _timer_H_

/*--------------------------------------------------------------------------*/
/* DEFINES */
/*--------------------------------------------------------------------------*/

    /* -- (none) -- */

/*--------------------------------------------------------------------------*/
/* INCLUDES */
/*--------------------------------------------------------------------------*/

#include <stdio.h>
#include <sys/time.h>
#include <list>
#include <stdlib.h>
#include <signal.h>
#include <pthread.h>
#include "semaphore.H"
#include <unistd.h>
#include <iostream>
/*--------------------------------------------------------------------------*/
/* DATA STRUCTURES */ 
/*--------------------------------------------------------------------------*/


/*--------------------------------------------------------------------------*/
/* FORWARDS */ 
/*--------------------------------------------------------------------------*/

    /* -- (none) -- */

/*--------------------------------------------------------------------------*/
/* CLASS   T i m e r  */
/*--------------------------------------------------------------------------*/

using namespace std;

class Timer {
private:
  static long clock_interval; /* in musec */
  
  static bool compare_timers(const Timer * _t1, const Timer * _t2);
  /* Compares whether timer _t1 is earlier than timer _t2. This function
     may come in handy, for example, whenever timers need to be inserted into
     an ordered queue. */
  // ACESSORY FUNCTION TO COMPARE TIMEVALS
  static bool compare_tv(timeval ta, timeval tb);

  static void * TimerHandlerThread(void * args);
  /* This function is called by the separate thread that handles the low-level
     timer interrupts and checks whether timers events have expired and
     need to be executed. */

  /* WHEN SHOULD THE TIMER FIRE? */
  timeval tv;
  static list<Timer*> timeq;
  static Semaphore * s; 

public:

  static int Init(long _clock_interval_musec);
  /* Initialize the timer handling. This should be called by the main 
     thread early on, certainly before it creates the first timers.
     An implementation could look as follows: First, the main thread masks the
     SIGALARM (or SIGVTALARM) signals; this should be done before any 
     tasks are created, in order for the tasks to have the signals masked. 
     Then, method "Init()" would create a new timer thread, which would 
     process the requests in the timer queue. For this thread, the 
     signal would be unblocked. */
 
  Timer();
  /* Construct timer that calles "Event_Handler" whenever it fires. */

  ~Timer();

  virtual void Set(long _imusec);
  /* Set this timer to fire after time '_imusec' from now. */

  virtual int Clear();
  /* Cancel the timer. */

  virtual void Handle_Event() = 0;
  /* This function is called when the timer expires. */

};

#endif




timer.C

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include "timer.H"

Timer::Timer() {
    s = new Semaphore(1);    
}

bool Timer::compare_tv(timeval ta, timeval tb) {
   if(ta.tv_sec < tb.tv_sec) {
        return true;
   }
   else if(ta.tv_sec > tb.tv_sec) {
        return false;
   }
   else if(ta.tv_sec == tb.tv_sec) {
        if(ta.tv_usec < tb.tv_usec) {
            return true;
        }
        else if(ta.tv_usec > tb.tv_usec) {
            return false;
        }
        else if(ta.tv_usec == tb.tv_usec) {
            return false;
        }
   }
}

bool Timer::compare_timers(const Timer * _t1, const Timer * _t2) {
        if(_t1->tv.tv_sec < _t2->tv.tv_sec) {
            return true;
        }
        else if(_t1->tv.tv_sec > _t2->tv.tv_sec) {
            return false;
        }
        else if(_t1->tv.tv_sec == _t2->tv.tv_sec) {
            if(_t1->tv.tv_usec < _t2->tv.tv_usec) {
                return true;
            }
            else if(_t1->tv.tv_usec > _t2->tv.tv_usec) {
                return false;
            }
            else if(_t1->tv.tv_usec == _t2->tv.tv_usec) {
                return false;
            }
        }
}

//HANDLER
void * Timer::TimerHandlerThread(void * args) {
    
    long sec = clock_interval / 1000000;
    long usec = clock_interval % 1000000;
    
    struct itimerval itv;
    itv.it_value.tv_sec = sec;
    itv.it_value.tv_usec = usec;
    itv.it_interval.tv_sec = sec;
    itv.it_interval.tv_usec = usec;
    setitimer(ITIMER_REAL, &itv, 0);
    
    sigset_t sg;
    int sgcount = 0;
    int signo;

    if((sigemptyset(&sg) == -1) || (sigaddset(&sg,SIGUSR1)== -1) || (sigprocmask(SIG_BLOCK, &sg, NULL) == -1))
        perror("Failed to block signal before sigwait\n");
        fprintf(stderr, "This process has ID %ld\n", (long)getpid());
    for( ; ; ) {
        if(sigwait(&sg, &signo) == -1) {
            perror("failed to wait using sigwait");
        }
        //get current time and compare with timers in queue to see if expired
        s->P();
        timeq.front()->Handle_Event();
        timeq.pop_front();
        s->V();
        sgcount++;
       
        timeval temp;
        gettimeofday(&temp, NULL);
        
        if(compare_tv(temp, timeq.front()->tv)) {
            timeq.pop_front();
        }
    }
    
   //check timer in list and pop??? 
}

//INIT
int Timer::Init(long _clock_interval_musec) {
    pthread_t pt;
    int x;
    sigset_t sigset;   
    clock_interval = _clock_interval_musec;

    //Set(clock_interval);
    sigemptyset(&sigset);
    sigaddset(&sigset, SIGALRM);//TIMER_SIGNAL
    sigprocmask(SIG_BLOCK, &sigset, NULL);

    x=pthread_create(&pt, NULL, TimerHandlerThread, NULL);
    if(x) {
        printf("ERROR\n");
        exit(-1);
    }
    pthread_detach(pt);
    return 0;
}

//SET
void Timer::Set(long _imusec) {
    Clear();
    gettimeofday(&tv, NULL);
    tv.tv_sec += _imusec/1000000;
    tv.tv_usec += _imusec%1000000;
    s->P();
    timeq.push_back(this);
    s->V();
    //push back the current time + timeval
}

//CLEAR
int Timer::Clear() {
    s->P();
    timeq.remove(this);
    s->V();
    //remove current timer from  queue
}



Timer::~Timer() {}


I'm pretty sure it doesn't have to do with how I am compiling it so it's in my code, but I am not sure what to do. Any help would be greatly appreciated. When I compiled I did not forget timer.C, also had to remove a few error lines because of length, but I think you get the idea

/tmp/cclRk13A.o(.text+0x3b): In function `Timer::Timer[not-in-charge]()':
: undefined reference to `Timer::s'
/tmp/cclRk13A.o(.text+0xc1): In function `Timer::Timer[in-charge]()':
: undefined reference to `Timer::s'
/tmp/cclRk13A.o(.text+0x223): In function `Timer::TimerHandlerThread(void*)':
: undefined reference to `Timer::clock_interval'
/tmp/cclRk13A.o(.text+0x23f): In function `Timer::TimerHandlerThread(void*)':
: undefined reference to `Timer::clock_interval'
/tmp/cclRk13A.o(.text+0x379): In function `Timer::TimerHandlerThread(void*)':
: undefined reference to `Timer::s'

: undefined reference to `Timer::timeq'
/tmp/cclRk13A.o(.text+0x3a8): In function `Timer::TimerHandlerThread(void*)':
: undefined reference to `Timer::timeq'
/tmp/cclRk13A.o(.text+0x3b9): In function `Timer::TimerHandlerThread(void*)':
: undefined reference to `Timer::s'
/tmp/cclRk13A.o(.text+0x3e5): In function `Timer::TimerHandlerThread(void*)':
: undefined reference to `Timer::timeq'

: undefined reference to `Timer::timeq'

: undefined reference to `Timer::clock_interval'
/tmp/cclRk13A.o(.text+0x57d): In function `Timer::Set(long)':
: undefined reference to `Timer::s'
/tmp/cclRk13A.o(.text+0x597): In function `Timer::Set(long)':
: undefined reference to `Timer::timeq'

: undefined reference to `Timer::s'
/tmp/cclRk13A.o(.text+0x5c7): In function `Timer::Clear()':
: undefined reference to `Timer::s'

: undefined reference to `Timer::timeq'
/tmp/cclRk13A.o(.text+0x5f2): In function `Timer::Clear()':
: undefined reference to `Timer::s'
collect2: ld returned 1 exit status
Last edited on
closed account (S6k9GNh0)
Undefined references means that something you declared and used has no implementation. Since you haven't provided us with the neccessary error message, we can't tell you what the compiler expects.
Let me guess, you have a main.c file that #includes timer.h, but you never added timer.c to the compiler/linker arguments, causing the undefined references to the timer classes methods.
So what exactly are the errors? Just copy+pasting them is fine.
Errors are in the edit above. Thanks for the help
You can't access static variables like they are member variables. Try using Timer::s or whatever when you are accessing the statics.
I tried that and it did not fix any of the errors.
I don't see where you've actually defined any of your static members.

In timer.C you should have (at file scope):

1
2
3
  long Timer::clock_interval;
  list<Timer*> Timer::timeq;
  Semaphore * Timer::s;


Declaring them in the class isn't enough.



firedraco wrote:
You can't access static variables like they are member variables.


It's a bit counter-intuitive, but it is perfectly legal.
Last edited on
Thanks cire! That was it! Forgot to do that
Topic archived. No new replies allowed.