3

I am fairly new to C and am going over some code to learn about hashing.

I came across a file that contained the following lines of code:

#include <stdio.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>

#include <time.h>
#include <sys/time.h>

// ---------------------------------------------------------------------------

int64_t timing(bool start)
{
    static      struct timeval startw, endw; // What is this?
    int64_t     usecs   = 0;

    if(start) {
        gettimeofday(&startw, NULL);
    }
    else {
        gettimeofday(&endw, NULL);
        usecs   =
               (endw.tv_sec - startw.tv_sec)*1000000 +
               (endw.tv_usec - startw.tv_usec);
    }
    return usecs;
}

I have never come across a static struct defined in this manner before. Usually a struct is preceded by the definition/declaration of the struct. However, this just seems to state there are going to be static struct variables of type timeval, startw, endw.

I have tried to read up on what this does but have not yet found a good enough explanation. Any help?

SeekingAlpha
  • 7,489
  • 12
  • 35
  • 44
  • 1
    A static struct is no different from a static int. Do you know how static local variables work? – Jon Mar 08 '14 at 15:06
  • I think it's because fuction timing is called a lot , so define it to be static,which is defined only one time. – michaeltang Mar 08 '14 at 15:10
  • @Jon: yes I do I read this article [here](http://stackoverflow.com/questions/4576607/static-keyword-in-ansi-c). Like I said I am new and searching online did not yield a very good explanation hence I opened this question to all who can and is willing to help me. – SeekingAlpha Mar 08 '14 at 15:15
  • 1
    @michaeltang Not really (allocating on stack doesn't add much). `timing` is *stateful* function, on `timing(false)` it returns time difference from last `timing(true)`. – user3125367 Mar 08 '14 at 15:17

2 Answers2

6

struct timeval is a struct declared somewhere in sys/time.h. That line you highlighted declares two static variables named startw and endw of type struct timeval. The static keyword applies to the variables declared, not the struct (type).

You're probably more used to structs having a typedef'd name, but that's not necessary. If you declare a struct like this:

struct foo { int bar; };

Then you've declared (and defined here) a type called struct foo. You'll need to use struct foo whenever you want to declare a variable (or parameter) of that type. Or use a typedef to give it another name.

foo some_var;              // Error: there is no type named "foo"
struct foo some_other_var; // Ok
typedef struct foo myfoo;
myfoo something_else;      // Ok, typedef'd name
// Or...
typedef struct foo foo;
foo now_this_is_ok_but_confusing;
Mat
  • 202,337
  • 40
  • 393
  • 406
  • Thank you that really helped me understand it more. I was thinking that timeval must be a struct defined in a header file somewhere but I was not sure how to check? I tried man timeval in the terminal but that yielded nothing (I guess this is because it is a struct). Do you have any tips on how I can check in the future if a struct is declared in a header file somewhere in the standard C library? – SeekingAlpha Mar 08 '14 at 15:18
  • The man page for the function that requires (or returns) that type will list the headers it needs. So it'll be one of them. You understand that this is plain C syntax for using a `struct` though, right? There's nothing special about `struct timeval` in particular or the fact that it's defined in a system header. – Mat Mar 08 '14 at 15:20
  • I see. I thought there was a trick or something that you did that made you immediately know that it is defined in that header file. But it seems you just know from experience......I wish I can reach that level soon. Thanks for the thorough answer. Much appreciated. – SeekingAlpha Mar 08 '14 at 15:22
2

Here the important point is the static local variable. Static local variable will be initialized only one time, and the value will be saved and shared in the hole program context. This means the startw and endw will be used on next timing invoked.

In the program, you can invoke the timing many times:

timing(true);
//startw will be initialzed
timing(false);
//endw is initialized, and the startw has been saved on the prevous invoking.
......

I hope my description is clear. You can see the static local variable is static variable will be saved in global context.

QJGui
  • 907
  • 8
  • 10