What is time_t ultimately a typedef to?

后端 未结 10 2053
陌清茗
陌清茗 2020-11-22 08:34

I searched my Linux box and saw this typedef:

typedef __time_t time_t;

But I could not find the __time_t definition.

相关标签:
10条回答
  • 2020-11-22 09:02

    The answer is definitely implementation-specific. To find out definitively for your platform/compiler, just add this output somewhere in your code:

    printf ("sizeof time_t is: %d\n", sizeof(time_t));
    

    If the answer is 4 (32 bits) and your data is meant to go beyond 2038, then you have 25 years to migrate your code.

    Your data will be fine if you store your data as a string, even if it's something simple like:

    FILE *stream = [stream file pointer that you've opened correctly];
    fprintf (stream, "%d\n", (int)time_t);
    

    Then just read it back the same way (fread, fscanf, etc. into an int), and you have your epoch offset time. A similar workaround exists in .Net. I pass 64-bit epoch numbers between Win and Linux systems with no problem (over a communications channel). That brings up byte-ordering issues, but that's another subject.

    To answer paxdiablo's query, I'd say that it printed "19100" because the program was written this way (and I admit I did this myself in the '80's):

    time_t now;
    struct tm local_date_time;
    now = time(NULL);
    // convert, then copy internal object to our object
    memcpy (&local_date_time, localtime(&now), sizeof(local_date_time));
    printf ("Year is: 19%02d\n", local_date_time.tm_year);
    

    The printf statement prints the fixed string "Year is: 19" followed by a zero-padded string with the "years since 1900" (definition of tm->tm_year). In 2000, that value is 100, obviously. "%02d" pads with two zeros but does not truncate if longer than two digits.

    The correct way is (change to last line only):

    printf ("Year is: %d\n", local_date_time.tm_year + 1900);
    

    New question: What's the rationale for that thinking?

    0 讨论(0)
  • 2020-11-22 09:04

    time_t is just typedef for 8 bytes (long long/__int64) which all compilers and OS's understand. Back in the days, it used to be just for long int (4 bytes) but not now. If you look at the time_t in crtdefs.h you will find both implementations but the OS will use long long.

    0 讨论(0)
  • The time_t Wikipedia article article sheds some light on this. The bottom line is that the type of time_t is not guaranteed in the C specification.

    The time_t datatype is a data type in the ISO C library defined for storing system time values. Such values are returned from the standard time() library function. This type is a typedef defined in the standard header. ISO C defines time_t as an arithmetic type, but does not specify any particular type, range, resolution, or encoding for it. Also unspecified are the meanings of arithmetic operations applied to time values.

    Unix and POSIX-compliant systems implement the time_t type as a signed integer (typically 32 or 64 bits wide) which represents the number of seconds since the start of the Unix epoch: midnight UTC of January 1, 1970 (not counting leap seconds). Some systems correctly handle negative time values, while others do not. Systems using a 32-bit time_t type are susceptible to the Year 2038 problem.

    0 讨论(0)
  • 2020-11-22 09:14

    [root]# cat time.c

    #include <time.h>
    
    int main(int argc, char** argv)
    {
            time_t test;
            return 0;
    }
    

    [root]# gcc -E time.c | grep __time_t

    typedef long int __time_t;

    It's defined in $INCDIR/bits/types.h through:

    # 131 "/usr/include/bits/types.h" 3 4
    # 1 "/usr/include/bits/typesizes.h" 1 3 4
    # 132 "/usr/include/bits/types.h" 2 3 4
    
    0 讨论(0)
  • 2020-11-22 09:19

    time_t is of type long int on 64 bit machines, else it is long long int.

    You could verify this in these header files:

    time.h: /usr/include
    types.h and typesizes.h: /usr/include/x86_64-linux-gnu/bits

    (The statements below are not one after another. They could be found in the resp. header file using Ctrl+f search.)

    1)In time.h

    typedef __time_t time_t;
    

    2)In types.h

    # define __STD_TYPE     typedef  
    __STD_TYPE __TIME_T_TYPE __time_t;  
    

    3)In typesizes.h

    #define __TIME_T_TYPE       __SYSCALL_SLONG_TYPE  
    #if defined __x86_64__ && defined __ILP32__  
    # define __SYSCALL_SLONG_TYPE   __SQUAD_TYPE  
    #else
    # define __SYSCALL_SLONG_TYPE   __SLONGWORD_TYPE
    #endif  
    

    4) Again in types.h

    #define __SLONGWORD_TYPE    long int
    #if __WORDSIZE == 32
    # define __SQUAD_TYPE       __quad_t
    #elif __WORDSIZE == 64
    # define __SQUAD_TYPE       long int  
    
    #if __WORDSIZE == 64
    typedef long int __quad_t;  
    #else
    __extension__ typedef long long int __quad_t;
    
    0 讨论(0)
  • 2020-11-22 09:19

    Typically you will find these underlying implementation-specific typedefs for gcc in the bits or asm header directory. For me, it's /usr/include/x86_64-linux-gnu/bits/types.h.

    You can just grep, or use a preprocessor invocation like that suggested by Quassnoi to see which specific header.

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