Thread: Help with timersub(), implicit declaration warning!

  1. #1
    Registered User
    Join Date
    Sep 2020
    Posts
    6

    Arrow Help with timersub(), implicit declaration warning!

    I am making a program to track how long it takes a user to complete a task.

    Everything works relatively fine, but I get a warning on a line and I'm not sure why: "Implicit declaration of function 'timersub' is invalid in C99"

    The use of timersub in test(), works, I just don't understand the warning. I thought timersub was covered in time.h.

    Here is my code:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/time.h>
    #include <time.h>
    
    struct timeval start, stop, res;
    
    void welcome();
    void randomize (char *arr[], int n);
    void swap (char **a, char **b);
    double test (char *arr[], int n);
    
    //Main function
    int main()
    {
        char *arr[] = {
                "The",
                "quick",
                "brown",
                "fox",
                "jumps",
                "over",
                "the",
                "lazy",
                "dog"
        };
    
        int n = sizeof(arr)/sizeof(arr[0]); //Get total words in array.
        randomize(arr,n); //Pass array to randomizer.
    
        welcome();
        double timer = test(arr,n);
        printf("Test took %f seconds to complete.\n", timer);
        return 0;
    }
    
    //Function to display the welcome message.
    void welcome()
    {
        printf("Welcome to the Typing Speed Test.\n");
        printf("You will be given a random permutation of words to type.\n");
        printf("The timer will begin when the first word appears.\n");
        printf("You will not be able to move on to the next word until you\n");
        printf("correctly spell the word provided.\n");
        printf("Press ENTER to begin.\n");
        getchar();
    }
    
    //Function to randomize the words in an array.
    void randomize(char **arr, int n) {
    
        gettimeofday(&start,NULL);
        unsigned long time_ms = 1000000 * start.tv_sec + start.tv_usec;
        srand(time_ms);
    
        for (int i = n-1; i > 0; --i){
            int j = rand()%(i+1);
            swap (&arr[i], &arr[j]);
        }
    }
    
    //Function to swap two pointers in an array.
    void swap (char **a, char**b)
    {
        char *temp=*a;
        *a=*b;
        *b=temp;
    }
    
    //Function to run the typing test.
    double test(char *arr[], int n)
    {
    
        char str1[20];
        int correct;
    
        gettimeofday(&start, NULL);
        for (int i = 0; i < n; ++i){
            do{
                printf("Word number %d: %s\n", i+1, arr[i]);
                scanf("%10s", str1);
                if(strcmp(arr[i], str1) != 0){
                    printf("Incorrect.\n");
                    correct = 0;
                }
                else{
                    correct = 1;
                }
            } while (correct == 0);
        }
        gettimeofday(&stop, NULL);
    
        timersub(&start, &stop, &res);
    
        return res.tv_sec + res.tv_usec/1000000.0;
    }
    
    Any suggestions?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by confundido
    I thought timersub was covered in time.h.
    No, not in <time.h>: struct timeval and consequently timersub are not part of the C standard. From what I see it should be declared in <sys/time.h>, which you did include. So that's a little puzzling. What's your OS and what compiler did you use and with what compile options?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Sep 2020
    Posts
    6
    Quote Originally Posted by laserlight View Post
    No, not in <time.h>: struct timeval and consequently timersub are not part of the C standard. From what I see it should be declared in <sys/time.h>, which you did include. So that's a little puzzling. What's your OS and what compiler did you use and with what compile options?
    I was using CLion on a Windows OS, but I also tried Visual Studio, neither seem to want to work

    Code:
    [typing_test.c 2020-09-30 22:36:40.263]
    ,,typing_test.c: In function 'test':
    typing_test.c:93:5: warning: implicit declaration of function 'timersub' [-Wimplicit-function-declaration]
         timersub(&start, &stop, &res);
         ^~~~~~~~
    C:\...\ccuZAnq4.o:typing_test.c:(.text+0x29e): undefined reference to `timersub'
    collect2.exe: error: ld returned 1 exit status
    It definitely seems to be something on my system.
    When I run it on a Linux system it doesn't even give the error.

    So I need to figure out whats going on with my libraries/compilation.
    Last edited by confundido; 09-30-2020 at 04:39 PM.

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by confundido
    I was using CLion on a Windows OS.
    CLion is an IDE, not a compiler. My guess is that you're using the MinGW port of gcc, and if so, this appears relevant: Implicit declaration of timersub() function in Linux - what must I define?

    That is, you should configure CLion to provide the compiler with the options -D_DEFAULT_SOURCE -D_BSD_SOURCE

    This would be equivalent to writing at the top of each source file:
    Code:
    #define _DEFAULT_SOURCE
    #define _BSD_SOURCE
    Normally, #define statements should go after headers, but in this case we want them before the headers (presumably <sys/time.h> in particular) so as to enable certain declarations in the headers. So instead of changing the code in a way that may be meaningless for other compilers on other operating systems, configuring your IDE allows you to make the change for your particular setup.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Sep 2020
    Posts
    425
    Why not just go without timersub() and return

    (stop.tv_sec + stop.tv_usec/1000000.0) - (start.tv_sec + start.tv_usec/1000000.0)

  6. #6
    Registered User
    Join Date
    Sep 2020
    Posts
    6
    Quote Originally Posted by laserlight View Post
    CLion is an IDE, not a compiler. My guess is that you're using the MinGW port of gcc, and if so, this appears relevant: Implicit declaration of timersub() function in Linux - what must I define?
    Oh sorry, yes thats correct. I use MinGW via the IDE.

    That is, you should configure CLion to provide the compiler with the options -D_DEFAULT_SOURCE -D_BSD_SOURCE

    This would be equivalent to writing at the top of each source file:
    Code:
    #define _DEFAULT_SOURCE
    #define _BSD_SOURCE
    Normally, #define statements should go after headers, but in this case we want them before the headers (presumably <sys/time.h> in particular) so as to enable certain declarations in the headers. So instead of changing the code in a way that may be meaningless for other compilers on other operating systems, configuring your IDE allows you to make the change for your particular setup.
    I will give that a try.

  7. #7
    Registered User
    Join Date
    Sep 2020
    Posts
    6
    Quote Originally Posted by hamster_nz View Post
    Why not just go without timersub() and return

    (stop.tv_sec + stop.tv_usec/1000000.0) - (start.tv_sec + start.tv_usec/1000000.0)
    My professor is requiring the use of timersub

  8. #8
    Registered User
    Join Date
    Sep 2020
    Posts
    425
    Quote Originally Posted by confundido View Post
    My professor is requiring the use of timersub
    Oh, well if that is the case, I would start 'grep'ing (or 'findstr' on windows) through the header files to find which one has it....

  9. #9
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Quote Originally Posted by confundido View Post
    My professor is requiring the use of timersub
    I'd suggest that you develop your code on the Linux system - It's a good lesson on portability issues with non-standard C language features
    Fact - Beethoven wrote his first symphony in C

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. implicit declaration of function warning
    By cooper1200 in forum C Programming
    Replies: 3
    Last Post: 04-27-2019, 04:25 AM
  2. warning: implicit declaration of function 'scanf_s'
    By Bucephalus01 in forum C Programming
    Replies: 3
    Last Post: 08-21-2016, 06:54 AM
  3. gcc warning: implicit declaration of function
    By anatoly in forum C Programming
    Replies: 4
    Last Post: 05-02-2010, 04:32 PM
  4. warning: implicit declaration of function ‘malloc’
    By yougene in forum C Programming
    Replies: 3
    Last Post: 01-09-2009, 03:18 AM
  5. Implicit Declaration Warning
    By robosapien in forum C Programming
    Replies: 5
    Last Post: 04-02-2007, 08:35 PM

Tags for this Thread