none
timeval struct incorrect?

All replies

  • I am also facing this problem. My application uses Timeval structure extensively and uses it in calls to localtime() etc. [eg : struct tm *ttm = localtime(&(tv.tv_sec)); ]. It works in VC6 as type of Time_t was long in it. But now, it does not work in VC8, as type of Time_T in VC8 is __int64.  It compiles successfully, but crashes at runtime.

     

    Is a correct definition of timeval structure available?


    Bibin
    Wednesday, August 04, 2010 6:36 AM
  • Hello Bibin
    In the good old days time_t was defined in time.h as:

    #ifndef _TIME_T_DEFINED
    typedef long time_t;        /* time value */
    #define _TIME_T_DEFINED     /* avoid multiple def's of time_t */
    #endif

    With the 64 bit targets things coming a little more complicated, time.h has a dependency to crtdefs.h and time_t is not always a long anymore. The definitions of time_t are as followed:

    In crtdefs.h:

    #ifndef _TIME32_T_DEFINED
    typedef _W64 long __time32_t;   /* 32-bit time value */
    #define _TIME32_T_DEFINED
    #endif

    #ifndef _TIME64_T_DEFINED
    typedef __int64 __time64_t;     /* 64-bit time value */
    #define _TIME64_T_DEFINED
    #endif

    #ifndef _TIME_T_DEFINED
    #ifdef _USE_32BIT_TIME_T
    typedef __time32_t time_t;      /* time value */
    #else
    typedef __time64_t time_t;      /* time value */
    #endif
    #define _TIME_T_DEFINED         /* avoid multiple def's of time_t */
    #endif

    In time.h (depends on crtdefs.h):

    #ifndef _TIME_T_DEFINED
    #ifdef _USE_32BIT_TIME_T
    typedef __time32_t time_t;      /* time value */
    #else
    typedef __time64_t time_t;      /* time value */
    #endif
    #define _TIME_T_DEFINED         /* avoid multiple def's of time_t */
    #endif

    You see time_t can be a long or a __int64. To prevent time_t to be a 64bit value you must define "_USE_32BIT_TIME_T".

    But I'm not sure if this covers your crashing problem. I never had problems using time_t with 32 bit value and 64bit value also.

    Best regards

    Bordon

    Wednesday, August 04, 2010 11:43 AM
  • Hi Bordon,

    Thanks for the reply.

    I have already tried "_USE_32BIT_TIME_T". It does not work.

    The problem with "_USE_32BIT_TIME_T" is that it is a just a recommendation of the compiler. It works correctly if your target os/processor [in the vs compiler] is 32 bit. If the target os/processor is 64bit [vista/win7/titanium] then "_USE_32BIT_TIME_T" is ignored by the compiler [vs], which then proceeds to compile the 64bit versions of the functions.

     

    As I have not found any "official" workaround, I have written my own standard compliant [I hope so] timeval structure :

    struct timeval_std
       {
          time_t  tv_sec;         /* seconds */
          long tv_usec;    /* and microseconds */
       };

     

    Regards,

    Bibin

    • Proposed as answer by BibinVarghese Friday, August 06, 2010 12:29 PM
    Friday, August 06, 2010 5:23 AM
  • >If the target os/processor is 64bit [vista/win7/titanium] then "_USE_32BIT_TIME_T" is ignored by the compiler [vs], which then proceeds to compile the 64bit versions of the functions.

    Yes you're right my fault.

    >As I have not found any "official" workaround, I have written my own standard compliant [I hope so] timeval structure :

    For me it sounds a little strange having this 64bit issue. Can you post a small test code I can use on my 64bit target? I think the problem is not the 64bit time_t, I'm pretty sure there is somewhere a typecast or something like that that is the reason for the problem.

    Friday, August 06, 2010 5:58 AM
  • example code :

    struct timeval tv;

    struct tm     *ttm;

    gettimeofday(&tv);  //Returns the time of day in the "tv" variable.

    ttm = localtime(&(tv.tv_sec));       //Runtime crash.

    <blockquote><p>I think the problem is not the 64bit time_t, I'm pretty sure there is somewhere a typecast or something like that that is the reason for the problem.</p></blockquote>

    Typecasting would not work directly, because argument of localtime() is a pointer. Moreover, i would have to make the change at a lot of places.

    The main problem that i want to highlight is that definition of timeval given in winsock.h/winsock2.h is not compatible with the standard and is broken/erroneous wrt VC8.

     


    Bibin
    Friday, August 06, 2010 7:54 AM
  • Hello

    No I understand your problem complete :-)

    You are correct there are "incompatibilities" if you're building unter 64bits. The structure "timeval" is always as followed (32 and 64bit):

    struct timeval {
            long    tv_sec;         /* seconds */
            long    tv_usec;        /* and microseconds */
    };

    The time type "time_t" may be a "__int64" under 64bits or a "long" under 32 bits. And I guess that is the problem when you are using a pointer to member tv_sec the function localtime interprets the pointer to "tv.tv_sec" as 64bit pointer (__int64) and than the countent of the pointer is a combination of both timval stucture members.


    Example:

    struct timeval tv;
    time_t time;
    tv.tv_sec=0x123;
    tv.tv_usec=0x12356789;
    time=*((time_t*)&tv.tv_sec); //this is what happens in "localtime" time contains now value 0x12345678900000123 not 0x123


    You can check this behaviour if you debug your code and exchange the function "localtime with an own defined function. You'll see when you're in your own function that your value is a combination of the values stored in your timeval struct, and not the value of the tv_sec member.

    --------------------------------------
    To prevent such a behaviour I'd go the easiest way:
    struct tm *ttm;
    struct timeval tv; 
    time_t time;
     
    gettimeofday(&tv);  
    time=tv.tv_sec;
    ttm=localtime(&time);

    --------------------------------------
    Sorry for this many bits, bytes and pointers. You can sure define your own struct like you wrote in the postings above. This would work also.

    In general the 32 bit <--> 64 bit issues are not funny. When I was porting a source code from 32 bit only to 32 bit / 64 bit combined sourcecode it was a lot work to eliminate the 32 bit boundarys on a lot points in my partly more than 5 year old source code.

    • Proposed as answer by BibinVarghese Friday, August 06, 2010 12:28 PM
    Friday, August 06, 2010 11:14 AM