Thread: implicit declaration of function 'int rand_r(...)'

  1. #1
    Registered User
    Join Date
    Oct 2005
    Posts
    11

    implicit declaration of function 'int rand_r(...)'

    Code:
    #include <stdlib.h>
    
    typedef struct {
       pthread_t myTid;
       int myId;
       unsigned int seed;
       pthread_cond_t myCv;
    } State;
    State states[8];
    
    for(int y=0; y < 8; y++ ) {
          states[y].seed = getpid() + y;
    }
    
    int randNum = rand_r( &states[number].seed )%256;
    compiled with...
    $gcc ddr.c -lpthread -lrt

    Getting error in title and no idea why. My other use of rand_r seems fine.

    Code:
    State * statePtr = &states[number];
    long long totalTime = rand_r( &statePtr->seed)%120;

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    An implicit declaration means you're trying to use a function before you've described it to the compiler. This usually means you're not including the right header, or, you're trying to use it without having prototyped it. Like so:
    Code:
    int main( void )
    {
        foo( ); /* Trying to use 'foo' before we've seen it at all... */
        return 0;
    }
    
    void foo( void )
    {
        ...whatever...
    }
    Here main hasn't seen 'foo', so it doesn't know what you're trying to do. The solution to this is to move the function itself someplace in scope before you try calling it, or to prototype it.


    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Oct 2005
    Posts
    11
    I got the right header in. rand_r is a function in stdlib.h. It should be written as
    Code:
    int rand_r(unsigned int * seedptr);
    by what I've found in man and about 10 other websites.

    I have even tried switching the . to -> but that just gives me an extra error allong with the original. I even tried switching to a State pointer and using that like in my other call to rand_r to no avail. No idea what is causing it.

    Posting my whole thing but be warned, I know for a fact there are more errors things I haven't finished yet. I know I still need to fix my calls to nanosleep too. I'll fix those later, right now I just want to figure this thing out.

    Code:
    #include <sys/types.h>
    #include <sys/time.h>
    #include <pthread.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <iostream.h>
    
    enum { NUMTHREAD = 8, TRACKS = 256, TRANSFER = 3 };
    typedef enum { UP =1, DOWN = 0 } Direction;
    
    
    typedef struct {
       pthread_t myTid;
       int myId;
       unsigned int seed;
       pthread_cond_t myCv;
    } State;
    State states[NUMTHREAD];
    
    typedef struct {
       pthread_t myTid;
       int curTrack;
       pthread_cond_t myCv;
    } diskDrive;
    diskDrive diskDriver;
    
    typedef struct {
       long long threadTimes[NUMTHREAD];
       int count;
    } Queue;
    Queue threadQueue;
    
    static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
    static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
    
    long long totalTime;
    long long startTime;
    
    void queueinit( Queue * pq ) {
       pq->count = 0;
    }
    
    void enqueue( int id, Queue * pq ) {
       pq->threadTimes[id] = gethrtime();
       pq->count++;
    }
    
    int dequeue( Queue * pq ) {
       int check = 0;
       for( int i=1; i <= NUMTHREAD; i++ ) {
          if( check == 0 ) {
             check = i;
          } else if( pq->threadTimes[i] < pq->threadTimes[check]) {
             check = i;
          }
       }
       startTime = pq->threadTimes[check];
       return check;
    }
    
    void recordTime( long long aTime ) {
       pthread_mutex_lock( &mtx );
       totalTime = totalTime + aTime;
       pthread_mutex_unlock( &mtx );
    }
    
    void * DDR( void * arg) {
       int slot = 0, randNum, curTrack = 0;
       long long sleepTime, endTime, transTime;
       while ( true ) {
          pthread_cond_wait( &cond, &mtx );
          slot = dequeue( &threadQueue );
          randNum = rand_r( &states[slot].seed )%256;
          if( curTrack >= randNum ) {
             sleepTime = (( curTrack - randNum ) * 50000 + 3000000 );
          } else {
             sleepTime = (( randNum - curTrack ) * 50000 + 3000000 );
          }
          nanosleep( &sleepTime );
          endTime = gethrtime();
          transTime = endTime - startTime;
          recordTime( transTime );
          pthread_cond_signal( &states[slot].myCv );
       }
    }
    
    void * user( State * statePtr ) {
       long long thinkTime;
       for( int q=0; q < 125; q++) {
          thinkTime = (rand_r( &statePtr->seed)%120) / 2;
          thinkTime = thinkTime * 1000000;
          nanosleep( thinkTime );
          enqueue( statePtr->myId, &threadQueue);
          pthread_cond_signal( &diskDriver.myCv);
          pthread_cond_wait ( &cond, &mtx );
       }
    }
    
    int main() {
       queueinit( &threadQueue );
       for(int y=0; y < NUMTHREAD; y++ ) {
          states[y].seed = getpid() + y;
          states[y].myId = y + 1;
          pthread_cond_init( &states[y].myCv, NULL);
          pthread_create( &states[y].myTid, NULL, user, &states[y] );
       }
       pthread_create( &diskDriver.myTid, NULL, DDR, NULL);
       for(int j=0; j < NUMTHREAD; j++ ) {
          pthread_join( states[j].myTid, NULL);
       }
       cout << totalTime << endl;
       return 0;
    }

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    I got the right header in. rand_r is a function in stdlib.h. It should be written as
    Does this compile?
    Code:
    #include<stdlib.h>
    int main( void )
    {
        rand_r( NULL );
        return 0;
    }
    Quzah.
    Hope is the first step on the road to disappointment.

  5. #5
    Registered Luser cwr's Avatar
    Join Date
    Jul 2005
    Location
    Sydney, Australia
    Posts
    869
    If you are using the flags -ansi and -Wall, you will get the implcit declaration warning, because gcc ensures that only prototypes for ANSI C functions are included in the standard headers when -ansi is chosen. If you omit -ansi, the warning should disappear.

    rand_r is not an ANSI C function, it's a POSIX function, and the prototype will only be included if you define __USE_POSIX. gcc defines this by default, but undefines it with -ansi.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 8
    Last Post: 03-10-2008, 11:57 AM
  2. Replies: 1
    Last Post: 10-27-2006, 01:21 PM
  3. getting a headache
    By sreetvert83 in forum C++ Programming
    Replies: 41
    Last Post: 09-30-2005, 05:20 AM
  4. Binary Search Trees Part III
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 16
    Last Post: 10-02-2004, 03:00 PM
  5. My graphics library
    By stupid_mutt in forum C Programming
    Replies: 3
    Last Post: 11-26-2001, 06:05 PM