portable way to deal with 64/32 bit time_t

前端 未结 5 1459
轻奢々
轻奢々 2020-12-06 05:15

I have some code which is built both on Windows and Linux. Linux at this point is always 32bit but Windows is 32 and 64bit. Windows wants to have time_t be 64 bit and Linu

相关标签:
5条回答
  • 2020-12-06 05:42

    My favourite way of handling with the issue is:

    1. Re-define time_t and use the redefined time_t everywhere instead of unsigned long long etc.:
    #define  time_t  intmax_t  /* Or unsigned long long int, int64_t etc. */
    
    1. Use strftime every time that you want to convert the timestamp to a string instead of relying on format strings. Format strings are unreliable, and overflow/underflow errors in format strings are often painful to debug, and hard to find while doing static analysis.

    A time will come however when most of the Unix system and compilers out there must converge towards a 64-bit time_t. At least, I hope that that time comes before 2038.

    0 讨论(0)
  • 2020-12-06 05:53

    I think the only truly portable way is to use strftime to convert the time_t to a string.

    If you're sure that you're only operating on platforms where time_t is an int, you could cast to intmax_t (from stdint.h) and print it using PRIdMAX (from inttypes.h).

    0 讨论(0)
  • 2020-12-06 05:54

    According to the C standard, time_t is an arithmetic type, "capable of representing times". So, it could be double for example. (Posix mentions this more explicitly, and also guarantees that time() returns the number of seconds since the Epoch—the latter is not guaranteed by the C standard.)

    Maybe the cleanest solution is to convert the value to whatever type you want. You may want one of unsigned long long or unsigned long:

    printf("%llu\n", (unsigned long long)t);
    
    0 讨论(0)
  • 2020-12-06 06:00

    If you want to go with the macro specifier, I would recommend one minor tweak. Instead of encapsulating the entire specifier, encapsulate just the modifier:

    #ifdef 64_BIT_TIME
      #define TT_MOD "ll"
    #else
      #define TT_MOD ""
    #endif
    

    and then using it like this:

    printf("current time in seconds is: %" TT_MOD "u", time(0));
    

    The reason why is that while you primarily want the second in decimal, every so often you may want hex (or perhaps you want leading 0's). By only having the modifier there, you can easily write:

    "%" TT_MOD "x"   // in hex
    "%08" TT_MOD "d"  // left pad with 0's so the number is at least 8 digits
    
    0 讨论(0)
  • 2020-12-06 06:02

    Slight adjustment on Alok's answer, it's signed on both Windows and Linux, so:

    printf("%lld\n", t);
    

    is cleaner.

    0 讨论(0)
提交回复
热议问题