Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
int main(void)
{
       time_t now = time(NULL);
       if ( now \!= \-1 ) {
               fputs(ctime(&now), stdout);
       }
    return 0;

}

    The c standard mandates that time() return (time_t)(-1). Some systems may interpret (time_t)(-1) as something completely different from the integer  -1. This could lead to potential invalid comparison and therefore invalid output (or worse, depending on what else is put in the if statement). Therefore the correct code is as follows:

...

Code Block
int main(void)
{
      time_t now = time(NULL);
      if ( now \!= (time_t)-1 ) {
             fputs(ctime(&now), stdout);
    }
    return 0;

}

    In the code above the comparison will function as expected.    

    Recommendation #2:
    It is also important to be mindful that as Use difftime when subtracting time, and avoid other arithmetic operations when possible.

   The result of performing arithmetic operations on time_t are undefined. Even if your system's a result of time_t being implementation defined, performing arithmetic operations with integers or floating points may or may not change the time variable's type or overflow the variable. If on your system time_t is an integer, do not divide time_t by an integer if you want your code to work with other machines. In other words, when performing arithmetic operations on time_t, use other time_t's and not integers or floating points. The function mktime() can be used to generate time_t variables.  
    According to the C99 standard "The clock function returns the implementation's best approximation to the processor time used by the program since the beginning of an implementation-de?ned era related only to the program invocation. adding and subtracting times may or may not produce a meaningful result.
    However, situations do arise in which it is necessary to add and subtract time. In general, it should be avoided. If you must do so, below is described the "best guess" at how to add and subtract time.   

    Subtraction:

    C99 defines difftime(), which allows for the subtraction of two time types and returns a double representing the number of seconds between them. Always use difftime() and do not use arithmetic subtraction.

    Addition:

   C99 does not define any addition functions for time; the best thing to do when you need to add time is to not. However, if you must do so, it is best to write a custom function for the platform you are on (a good place to start on ideas for structure is the difftime() function for your platform).

    Recommendation #3:
    Use proper form when subtracting clock_t's for processing time.

    Often times you will wish to clock the amount of time it takes your processor to run a given process. The C99 standard specifies the clock() function for this particular purpose. "In order to measure the time spent in a program, the clock function should be called at the start of the program and its return value subtracted from the value returned by subsequent calls..." It is further specified "To determine the time in seconds, the value returned by the clock function should be divided by the value of the macro CLOCKS_PER_SEC. .." However, the question remains as to what the proper returned type of this operation should be. If you wish to determine how long a certain process required to operate, the C99 standard recommends code of the following form:If the processor time used is not available or its value cannot be represented, the function returns the value (clock_t)(-1)."

    Two common errors are made when performing this operation. They are illustrated below.

    Non-compliant Code

Code Block

int run_big_program() {
    clock_t start, finish;
    int seconds;
    start = clock();
    run_long_program() 
    finish = clock();
    seconds = ((finish-start
Code Block

clock_t begin, end;
mystery_t mystery;
begin=clock();
/* run process */
end=clock();
mystery = (end-begin)/CLOCKS_PER_SEC); 
    return seconds; 
}

    The problem here is: 1) the return values of clock() are not checked (this occurs in many implementations of this functionality) and 2) the return value seconds in inappropriate.

    The way to remedy this is to check for return values properly and use an appropriate data structure for the subtraction for the number of seconds. It is implied by the C standard that finish-start will return the number of clock cycles necessary for run_long_program(), so you can be fairly sure of that. It is also implied by the C standard that dividing by type of the macro CLOCKS_PER_SEC is traditionally an integerwill net you the number of seconds. What is not specified, however, the C99 standard makes no statement on its type. There is no guarantee as to the type or behavior of clock_t when divided by CLOCKthe type that will be yielded by dividing CLOCKS_PER_SEC other than it is an arithmetic type. It is possible for longer processes to check by the standard resolution of time_t as follows:

Code Block

time_t begin, end;
time_t difference;
start=time();
/* run process */
end =time();
difference=end-start;

    The type of time_t-time_t is in fact time_t, and after this point you can convert the difference into a more palatable format for human parsing. However, you are limited to the resolution of time_t, which is probably considerably less useful than the resolution of clock_t.

. The best recommendation is to look at the types defined in time.h and use a compatible (and large, to prevent overflow) type. The convention for linux and most x86 architectures seems to be to use a double.

    Compliant Code

Code Block

double run_big_program ()
{
    clock_t start, finish;
    double seconds;
    start = clock();
    if (start = (clock_t)(-1)){
        return -1.0;
    }
    run_long_program();
    finish = clock();
    if (finish = (clock_t)(-1)){
        return -1.0;
    }
    seconds = (double) (finish-start)/CLOCKS_PER_SEC;
    return seconds; 
}         

   When appropriate one should also check for overflow in seconds.
  Wiki Markup \[This article is incomplete. It will be finished at a later date.\]

Credits/Interesting Links:

- The original idea for this came from the C Language Gotchas site, accessible here

...