#1973 _USE_32BIT_TIME_T issue.

WSL
pending
Earnie Boyd
None
Bug
fixed
Feature_in_WSL_4.0
False
2014-12-14
2013-05-16
Earnie Boyd
No

Related

Issues: #1975
Issues: #1984

Discussion

1 2 3 4 > >> (Page 1 of 4)
  • Jan Nijtmans
    Jan Nijtmans
    2013-05-22

    I looked at your patch, for example:

    #if MSVCRT_VERSION >= 800
    #define _USE_32BIT_TIME_T 1
    #endif /* MSVCRT_VERSION >= 800 */
    

    I don't think that any mingw header should set _USE_32BIT_TIME_T.

    See: http://msdn.microsoft.com/en-us/library/1f4c8f33%28v=vs.80%29.aspx

    From this page:

    In Visual C++ 2005, time is a wrapper for _time64 and time_t is, by
    default, equivalent to __time64_t. If you need to force the compiler
    to interpret time_t as the old 32-bit time_t, you can define
    _USE_32BIT_TIME_T.

    Regards,
    Jan Nijtmans

     
    Last edit: Earnie Boyd 2013-05-22
    • Earnie Boyd
      Earnie Boyd
      2013-05-22

      I don't think that any mingw header should set _USE_32BIT_TIME_T

      I agree. I have already removed it from my working area.

       
  • Twylite
    Twylite
    2013-05-22

    Following on from earnie's comments on the bug reported against Tcl: much of the confusion here seems to derive from not respecting the distinction between the C runtime library and headers, and the platform (WIN32/WIN64) libraries and header.

    If you are linking against MSVCRT.DLL (which is the C runtime) then you must compile against the corresponding headers (which don't understand and thus ignore _USE_32BIT_TIME_T). If you are compiling against headers for MSVCRT80 then you must link against MSVCRT80.

     
  • Jan Nijtmans
    Jan Nijtmans
    2013-05-22

    Here (See: mingw.patch) is my attempt to bring this issue forward. With this patch against today's git dev-4.0, Tcl 8.6 and earlier again compile fine without problems. I'm sure that it still contains problems, but for Tcl it works. The patch
    expects _HAVE_32BIT_TIME_T to be set when linking against MSVCRT80.dll or higher, _HAVE_32BIT_TIME_T should not be defined when linking against MSVCRT.dll. You will probably want to replace that with checks like "MSVCRT_VERSION >= 800".

    Regards,
    Jan Nijtmans

     
    Attachments
    • Earnie Boyd
      Earnie Boyd
      2013-05-22

      With this patch against today's git dev-4.0, Tcl 8.6 and earlier again compile fine without problems.

      Did you test on XP, the executable?

      The patch expects _HAVE_32BIT_TIME_T to be set when linking against MSVCRT80.dll or higher, _HAVE_32BIT_TIME_T should not be defined when linking against MSVCRT.dll. You will probably want to replace that with checks like "MSVCRT_VERSION >= 800".

      I'm removing the _HAVE_32BIT_TIME_T in favor of MSVCRT_VERSION; that change is in my working area, yet to be committed.

       
    • Earnie Boyd
      Earnie Boyd
      2013-05-22

      Is this the same patch as you added to the TCL ticket? If so, I've already tested it on XP and it did not work. The only thing I received during testing were SEGV errors.

       
  • Earnie Boyd
    Earnie Boyd
    2013-05-22

    Re: Twylite,

    2nd attempt, 500 error with the first.

    The issue is MSVCRT.DLL on XP does not contain the functions for _USE_32BIT_TIME_T. If _USE_32BIT_TIME_T is defined and one builds on a system whose MSVCRT.DLL supports the functions of _USE_32BIT_TIME_T and distributes that executable to someone using XP the XP user will have a sad experience. The issue with TCL is that the win/tclWinPort.h file sets _USE_32BIT_TIME_T explicitly. This causes the XP user to need to add -lmsvcr80 to build the application on XP while the Vista user could build TCL and execute it without -lmsvcr80 assuming the imports for the functions are added to libmsvcrt.a.

    Eventually I hope to resolve the issue in a later version of the MinGW runtime.

     
  • Jan Nijtmans
    Jan Nijtmans
    2013-05-22

    No, it's not the same patch as attached to the Tcl issue. I only tested it on Windows 7, but it should not use Win7-specific functions.

     
    • Earnie Boyd
      Earnie Boyd
      2013-05-22

      But _USE_32BIT_TIME_T is Vista and above specific for MSVCRT.DLL. If you take your executable to XP and try to execute it, you will not be able to.

       
  • Jan Nijtmans
    Jan Nijtmans
    2013-05-23

    With my patch (mingw.patch, attached here):
    $ nm tcl84.dll|grep I|grep time
    6297a6a0 I impftime
    6297a6b0 I __imp
    timezone
    6297a6b4 I
    imputime
    6297a6bc I __imp
    wutime
    6297a714 I impgmtime
    6297a71c I implocaltime
    6297a734 I impmktime
    629719e0 b _timeInfo

    Tcl doesn't use any of the "stat" functions, but this is
    what I expect for the "time"-related functions.

    Now, doing exactly the same with unpatched wsl-4.0-rc1 headers:
    $ nm tcl84.dll|grep I|grep time
    6297a6a0 I impftime64
    6297a6a4 I __imp
    gmtime64
    6297a6b0 I
    implocaltime64
    6297a6b4 I __imp
    mktime64
    6297a6bc I imptimezone
    6297a6c0 I __imp
    utime
    6297a6c8 I
    imp___wutime
    629719e0 b _timeInfo

    Which means that _USE_32BIT_TIME_T didn't do what it's
    supposed to do. It's wrong. mktime64 didn't exist in
    Win95/ME, so Tcl 8.4 wouldn't run there any more.

     
  • Twylite
    Twylite
    2013-05-23

    _USE_32BIT_TIME_T is not supposed to do what you're expecting it to do. It's supposed to call MSVCRT80+ functions that use a 32-bit time_t (i.e. gmtime32), as opposed to MSVCRT80+ functions that use a 64-bit time_t (i.e. gmtime64). It's not supposed to call MSVCRT (6.x) functions (i.e. gmtime).

    Defining _USE_32BIT_TIME_T doesn't magically allow your application to link against MSVCRT (6.x). It has nothing to do with MSVCRT 6.x. It's only understood by (the headers for) MSVCRT 8.x+ and will choose between two 8.x-specific behaviours (neither of which is backwards compatible with 6.x).

    http://msdn.microsoft.com/en-us/library/0z9czt0w%28v=vs.80%29.aspx: "In Visual C++ 2005, gmtime is an inline function which evaluates to _gmtime64 and time_t is equivalent to __time64_t. If you need to force the compiler to interpret time_t as the old 32-bit time_t, you can define _USE_32BIT_TIME_T. Doing this will cause gmtime to be in-lined to _gmtime32. This is not recommended because your application may fail after January 18, 2038, and it is not allowed on 64-bit platforms."

    This is implemented (in the MSVC headers) by include/time.inl.

    To resolve this problem you HAVE to match the headers with the CRT you are linking against. That either means pointing at a different include path for the CRT, or telling the compiler (via a preprocessor define) which CRT you're linking against and modifying the headers to do the right thing.

     
  • Twylite
    Twylite
    2013-05-23

    Earnie: "The issue with TCL is that the win/tclWinPort.h file sets _USE_32BIT_TIME_T explicitly. This causes the XP user to need to add -lmsvcr80 to build the application on XP while the Vista user could build TCL and execute it without -lmsvcr80 assuming the imports for the functions are added to libmsvcrt.a."

    No, the issue is that your compiler is supplying the headers for MSVCRT 8.x (or doing some trickery to achieve the equivalent), and linking against MSVCRT 6.x. The headers for MSVCRT 6.x don't understand _USE_32BIT_TIME_T and silently ignore it, so 'gmtime' resolves to the correct function in MSVCRT.DLL.

    Looking at https://sourceforge.net/p/mingw/mingw-org-wsl/ci/master/tree/include/time.h#l159 I can see the wrong assumption that is being made on line 156: it is assumed that if _USE_32BIT_TIME_T is defined then you want to link against the xxx32() functions. If you were compiling with MSVC the distinction would be more nuanced: MSVC6 headers (for MSVCRT.DLL v6.x) don't understand _USE_32BIT_TIME_T and link against the xxx() functions; MSVC8 headers (for MSVCRT80.DLL v8.x+) link against xxx64() functions by default (if _USE_32BIT_TIME_T is not defined) or xxx32() functions is _USE_32BIT_TIME_T is defined.

    The logic you want (in time.h) is:

      #if (MSVCRT_VERSION >= 800) && defined(_USE_32BIT_TIME_T) && defined(_HAVE_32BIT_TIME_T)
        // inline functions xxx() that call xxx32() in MSVCRT80+.DLL
      #elif (MSVCRT_VERSION >= 800)
        // inline functions xxx() that call xxx64() in MSVCRT80+.DLL
      #else
        // no special handling, functions xxx() are in MSVCRT.DLL
      #endif
    

    This of course assumes that the compiler is given the correct MSVCRT_VERSION for the lib you are going to link against.

     
    Last edit: Keith Marshall 2013-05-23
  • Jan Nijtmans
    Jan Nijtmans
    2013-05-23

    The logic you want (in time.h) is:
    ...
    Or, if you assume Windows XP with 64-bit time_t by default:

    #ifndef _USE_32BIT_TIME_T
    // inline functions xxx() that call xxx64() in any MSVCRT??.DLL
    #elif (MSVCRT_VERSION >= 800)
    // inline functions xxx() that call xxx32() in MSVCRT80+.DLL
    #else
    // no special handling, functions xxx() are in MSVCRT.DLL
    #endif
    

    Then, a user who requires 95/98/ME compatibility has two
    options to get it:
    1) define _USE_32BIT_TIME_T, which gives back a 32-bit time_t
    2) set MSVCRT_VERSION to 800 and link with -lmsvcrt80
    (and distribute msvcrt80.dll with the application).
    That would work fine too, although it's not 100%
    compatible with what Microsoft does. For Tcl this
    would work fine.

     
    Last edit: Keith Marshall 2013-05-23
  • Keith Marshall
    Keith Marshall
    2013-05-23

    Guys,

    Please use correct markup, for inlined code.

    These references to MSVCR80.DLL vs. MSVCRT.DLL v6.x aren't helpful. Neither are suggestions that users should rely on MSVCR80.DLL, and redistribute it. The bottom line is that MSVCR80.DLL, AFAIK, cannot be legitimately redistributed by anyone who lacks a paid for licence for a version of Visual Studio which grants that privilege; this is a non-free burden, which MinGW.org will never impose on its users.

    MinGW GCC links, by default, against MSVCRT.DLL, (the system DLL distributed as standard with every MS-Windows operating system). End of story: this is not negotiable. The issue here is that different versions of MS-Windows distribute incompatible variants of MSVCRT.DLL. It is these incompatibilities for which Earnie is attempting to implement a satisfactory work around -- I hesitate to say solution. One thing is certain: "redistribute MSVCR80.DLL" is not, and likely never will be, any part of that work around.

     
  • Twylite
    Twylite
    2013-05-23

    Apologies for the markup; I have not yet familiarized myself with SF's updated tracker.

    I'm not suggesting that you should redistribute MSVCR80.DLL if you don't want to; just that your headers must match your DLL.

    If you are linking against MSVCRT.DLL, then your headers must correctly translate gmtime() and friends into gmtime(), and not into gmtime32(). The (unpatched) headers attempt to call gmtime32() if _USE_32BIT_TIME_T is set, and gmtime64() otherwise, which is consistent with what you must do to link against MSVCRT80.DLL. When the C source asks for 'gmtime' your headers must supply a definition that links against your chosen runtime library (right now they don't).

    The logic I suggest works in all cases: by default it will resolve to names that link against MSVCRT.DLL; but if you choose to link against MSVCR80.DLL (and define MSVCRT_VERSION to 800 or higher) that will work too.

    If you don't use this logic then all projects that can be built with both MinGW GCC and MSVC need to have special handling for _USE_32BIT_TIME_T when building with MinGW GCC (because it doesn't respect the rule that headers must match the DLL) -- this is why Jan views this as a MinGW GCC bug and not a Tcl bug.

    With regards to the legality of redistributing MSVCR80+: Microsoft makes the redist installers available for free download (search for 'vcredist_x86.exe'). MSVCR110.DLL is redistributable with your application if you have a (free) license for MSVS 2012 Express (see http://msdn.microsoft.com/en-US/vstudio/hh857605). I understand the situation for earlier MSVCR*.DLL was less clear.

     
  • Twylite
    Twylite
    2013-05-23

    @Jan: "Or, if you assume Windows XP with 64-bit time_t by default:"

    What? This is not what the Microsoft C runtime headers do (which is what MinGW GCC should be trying to emulate, since they want to link against Microsoft's runtime DLL(s)).

    Moreover there is no support for 64-bit time_t on XP unless you redistribute MSVCR80+. MSVCRT.DLL does not have xxx64() functions, so your proposed change means that every project WITHOUT _USE_32BIT_TIME_T won't link. That's a hostile approach.

     
    • Keith Marshall
      Keith Marshall
      2013-05-23

      Moreover there is no support for 64-bit time_t on XP unless you redistribute MSVCR80+. MSVCRT.DLL does not have xxx64() functions ...

      Err ... no, this is not so. On XP:

      pexports msvcrt.dll | grep time
      

      shows me that, e.g., both _time64() and time() are available; it is _time32() which is lacking -- presumably time() itself is equivalent to the _time32() of later versions.

      OTOH, on Win7, the same command shows me that all three of time(), _time32(), and _time64() are exported. Reading between the lines of MSDN, it seems likely that by the time, (no pun intended), that MSVCRT.DLL had evolved to the Win7 version, (with the change apparently occurring in Vista), time() has become a trampoline for _time64(), unless a compile time redirection to _time32() is mandated by the inclusion of a definition for _USE_32BIT_TIME_T.

      If you are linking against MSVCRT.DLL, then your headers must correctly translate gmtime() and friends into gmtime(), and not into gmtime32(). The (unpatched) headers attempt to call gmtime32() if _USE_32BIT_TIME_T is set, and gmtime64() otherwise, which is consistent with what you must do to link against MSVCRT80.DLL

      Again ... no, not entirely; it is also consistent with the requirement, AIUI, when linking against MSVCRT.DLL, on Win7 (or perhaps Vista) and later. You are correct in respect of XP, however. The issue is that the goal posts move, depending on which MS-Windows version the end user has.

      ... Jan views this as a MinGW GCC bug and not a Tcl bug.

      It's likely that Earnie hasn't got it right yet, but I'd contend that it is actually a bug in both; it will just manifest differently for the two products, depending on which version of MS-Windows the end user happens to deploy on.

       
  • Earnie Boyd
    Earnie Boyd
    2013-05-23

    It's likely that Earnie hasn't got it right yet, but I'd contend that it is actually a bug in both; it will just manifest differently for the two products, depending on which version of MS-Windows the end user happens to deploy on.

    And of greater concern are those that build with MSVCRT.DLL supporting _USE_32BIT_TIME_T's *32 functions and try to distribute to XP. That is why I consider it a TCL issue; maybe not a bug but it will be a big surprise to many projects using TCL as a library of choice. SourceNavigator comes to mind.

    I'll review the code to determine if I can do some trickery for the case of MSVCRT_VERSION < 800 and _USE_32BIT_TIME_T is defined. I think it will be beneficial to any using GCC but that will not be equivalent to what MSVC does but we're not anywhere near equivalent anyway. The best thing will be to create __mingwrt_* equivalents so that we don't have any surprises for those distributing software; maybe for 5.x series.

     
  • Twylite
    Twylite
    2013-05-23

    Let me rephrase this from the perspective of a developer using MSVC. The last MS compiler that links against MSVCRT.DLL by default is MSVC6. The C runtime headers shipped with MSVC6 have no reference to *time64() at all.

    Windows XP shipped with MSVCRT.DLL ver 7.0, which includes the time64() functions. To access them you need to use headers in the platform SDK. All platform SDKs that support Windows XP provide time64() definitions. The last platform SDK that works with MSVC6 is Feb 2003 (Win2003 SP1); all SDKs up to and including that one always use a 32-bit time_t for a 32-bit compile (and a 64-bit time_t for a 64-bit compile). So if you wanted to use a 64-bit time_t in a 32-bit app then you used __time64_t and explicitly called *time64().

    If you are building with a compiler later than MSVC6 then you will link against an MSVCRxx.DLL (xx > 70), and the C runtime headers shipped with the compiler expect that you are going to link against that DLL.

    So if I as an MSVC-based developer compile a source tree for a 32-bit app with MSVC6 (so that it will run on any XP+ PC without me redistributing an MSVCRxx.DLL) then (1) when I declare a time_t it will be 32-bit; (2) when I call localtime() it will resolve to MSVCRT.DLL:localtime; and (3) it doesn't matter whether or not _USE_32BIT_TIME_T is defined in the source.

    If I compile the same source tree as a 32-bit app with MSVC2005-2012 then (1) when I declare a time_t it will be 32-bit if _USE_32BIT_TIME_T is defined and 64-bit otherwise; (2) when I call localtime() it will resolve to MSVCRxx.DLL:localtimeyy() where yy is 32 if _USE_32BIT_TIME_T is defined and 64 otherwise; and (3) I must redistribute MSVCRxx.DLL.

    So sources with _USE_32BIT_TIME_T defined will compile and link correctly with all versions of the MSVC compiler. Sources without _USE_32BIT_TIME_T may behave differently between MSVC6 and MSVC2005+.

    So if you want to maintain source compatibility for 32-bit builds (I'm assuming that's the goal) then (A) if the source has _USE_32BIT_TIME_T then you must use a 32-bit time_t; (B) if you're linking against MSVCRT.DLL then you must call time() for a 32-bit time_t, or time64() for a 64-bit time_t -- ignore the fact that some versions of MSVCRT export time32(), these aren't prototyped in any MS header for MSVCRT.DLL (in either VC6 or the platform SDK) so they don't officially exist ; (C) if the source doesn't have _USE_32BIT_TIME_T then you need to decide on whether you're going to emulate MSVC6 or MSVC2005+ behaviour (the former assumes 32-bit time_t, the latter assumes 64-bit time_t); (D) if you want to allow the option to link against MSVCR80+ then (D.1) time_t should default to 64-bits in the absence of _USE_32BIT_TIME_T and (D.2) time() should resolve to *time32() for 32-bit time_t.

    Point (B) above assumes that newer versions of MSVCRT.DLL have time() equivalent to time32() (rather than *time64() ). This must be the case if apps built with MSVC6 run on Windows 7.

    Depending on your answer to (C), Jan's proposal (that I previously argued against) may be right, assuming similar preprocessor logic around the definition of time_t.

     
  • Twylite
    Twylite
    2013-05-23

    Earnie: "And of greater concern are those that build with MSVCRT.DLL supporting _USE_32BIT_TIME_T's *32 functions and try to distribute to XP. That is why I consider it a TCL issue"

    Is there a disconnect between who chooses the headers and who chooses the library? That is, does GCC supply the C runtime headers, and Tcl's Makefile explicitly links against 'msvcrt.lib' or something like that? Then I can characterise this as a Tcl build problem.

    But as I see it, Tcl calls e.g. localtime(). The C runtime headers offered up by MinGW GCC turn that into _localtime32(). Then GCC links against msvcrt.lib (which may not have a _localtime32). That's quite clearly a MinGW GCC issue.

     
  • Twylite
    Twylite
    2013-05-28

    Hi,

    +# if defined(_USE_32BIT_TIME_T) && MSVCRT_VERSION >= 800
        typedef __time32_t time_t;
     # else
        typedef __time64_t time_t;
    

    So if my code says "_USE_32BIT_TIME_T" it means "make time_t 32-bit, unless I'm linking against an old version of MSVCRT, in which case make it 64-bit" ?

    If I declare a function "extern int My_GetTime(time_t *t);" then:

    (1) without _USE_32BIT_TIME_T: MinGW gives me a 64-bit time_t; MSVC6 gives a 32-bit time_t; MSVC2005+ gives a 64-bit time_t.

    (2) with _USE_32BIT_TIME_T: MinGW gives me a 64-bit time_t with MSVCRT.DLL or a 32-bit time_t with MSVCR80.DLL; MSVC6 gives a 32-bit time_t; MSVC2005+ gives a 32-bit time_t.

    Were I to link a DLL built with MinGW into an app built with MSVC, or vice versa, there would be a type size mismatch and memory overwriting. There is no source level compatibility here.

    The define "_USE_32BIT_TIME_T" means "make time_t 32-bit". If you can't do that then raise a preprocessor error. I should never get a 64-bit time_t if "_USE_32BIT_TIME_T" is defined. A side-effect of the define is that the headers must arrange for localtime(), gmtime() and friends to be mapped only library functions that handle a 32-bit time_t (irrespective of what they are called; _USE_32BIT_TIME_T does NOT mean 'call the xxx32()' functions, that's just a consequence of MS's function naming choices in MSVCR80.DLL).

     
    • Earnie Boyd
      Earnie Boyd
      2013-05-28

      Twylite, thanks for the insightful feedback. I'm close to stating that our minimum supported version is XP and MSVC version 7.10. If I do that then what we have works. Else I need to do some better digging of old data type structures. Or maybe just do

      #if MSVCRT_VERSION >= 800
      #ifdef _USE_32BIT_TIME_T
      typedef __time32_t time_t
      #else
      typedef __time64_t time_t
      #endif
      #elif MSVCRT_VERSION >= 700
      typedef __time64_t time_t
      #else
      typedef long time_t
      #endif
      

      What did the MSVCRT_VERSION 700 do with time_t?

       
  • Jan Nijtmans
    Jan Nijtmans
    2013-05-28

    Here is my patch (mingw2.patch), based on current wsl-4.0. It removes the warning
    "Your MSVCRT_VERSION does not support the use of _USE_32BIT_TIME_T",
    and makes the necessary changes such that msvcrt.dll (version 7.1
    or later) support _USE_32BIT_TIME_T just fine. The explanation why this
    works, can be found in this earlier in this ticket (Thanks, Twylite, for
    your very clear comments). This patch assumes the VS2005+ behavior:
    time_t is 64-bit, unless _USE_32BIT_TIME_T is specified. By default
    it will work on XP or higher, when _USE_32BIT_TIME_T is specified it
    should work on Windows 95/98/ME as well.

     
    Attachments
  • Twylite
    Twylite
    2013-05-28

    Hi Jan,

     _CRTIMP int __cdecl __MINGW_NOTHROW    _utime32 (const char*, struct __utimbuf32*);
    ... 
     #ifndef _USE_32BIT_TIME_T
    +_CRTALIAS int __cdecl __MINGW_NOTHROW  _utime (const char* _v1, struct _utimbuf* _v2)     { return(_utime32  (_v1,(struct __utimbuf32*)_v2)); }
    

    System32\MSVCRT.DLL 7.0.2600.0, 2001-Aug-17 (original Windows XP Pro release):

    C:\Temp>dumpbin /exports msvcrt.dll | findstr time
    3B7D6E72 time date stamp Fri Aug 17 21:20:18 2001
         79   4D 00034DCE _Strftime
        143   8D 0000EBB6 __p__timezone
        222   DD 00034E1B _ctime64
        279  116 00034E34 _ftime
        280  117 00034F1B _ftime64
        283  11A 00035018 _futime
        284  11B 00035195 _futime64
        299  12A 00035318 _getsystime
        305  130 000353DC _gmtime64
        361  168 00035601 _localtime64
        433  1B0 00035A52 _mktime64
        480  1DF 00035373 _setsystime
        513  200 00035ACF _strtime
        523  20A 00035B36 _time64
        524  20B 0004AFD0 _timezone
        539  21A 0003515E _utime
        540  21B 000352E1 _utime64
        546  221 000361D8 _wasctime
        565  234 000362B4 _wctime
        566  235 000362CD _wctime64
        621  26C 00036363 _wstrtime
        630  275 000363DA _wutime
        631  276 00036411 _wutime64
        638  27D 00036448 asctime
        653  28C 000365CD ctime
        654  28D 000365E6 difftime
        693  2B4 000365F7 gmtime
        724  2D3 000366FE localtime
        737  2E0 00036A3F mktime
        772  303 00034E00 strftime
        791  316 00036A4C time
        812  32B 00036A85 wcsftime
    

    System32\MSVCRT.DLL 7.0.2600.5512, 2008-Apr-14 (XP SP3 revision):

    C:\Temp>dumpbin /exports msvcrt.dll | findstr time
    480237A2 time date stamp Sun Apr 13 18:41:06 2008
         79   4D 00039094 _Strftime
        143   8D 0000F26A __p__timezone
        222   DD 000390EF _ctime64
        279  116 00039113 _ftime
        280  117 00039224 _ftime64
        283  11A 00039351 _futime
        284  11B 000394DE _futime64
        300  12B 00039671 _getsystime
        306  131 00039743 _gmtime64
        362  169 0003996F _localtime64
        434  1B1 00039DCE _mktime64
        481  1E0 000396D3 _setsystime
        514  201 00039E5C _strtime
        524  20B 00039ECA _time64
        525  20C 0004FFD0 _timezone
        540  21B 0003949E _utime
        541  21C 00039631 _utime64
        547  222 0003A5D5 _wasctime
        566  235 0003A6BC _wctime
        567  236 0003A6E0 _wctime64
        622  26D 0003A788 _wstrtime
        631  276 0003A806 _wutime
        632  277 0003A846 _wutime64
        639  27E 0003A886 asctime
        654  28D 0003AA1D ctime
        655  28E 0003AA41 difftime
        694  2B5 0003AA59 gmtime
        725  2D4 0003AB69 localtime
        738  2E1 0003AEB8 mktime
        773  304 000390CD strftime
        792  317 0003AECF time
        813  32C 0003AF0F wcsftime
    

    There are no xxx32() functions in there.

    I don't see how _utime() can ever be a wrapper around _utime32() and work on a basic install of Windows XP with no added libraries. _utime() only needs to resolve to _utime32() if you are linking against MSVCRT80+.

    Jan & Earnie: I think the logic we are looking for is the following. I've introduced a define _TIME_T_IS_32BIT to help clarify that _USE_32BIT_TIME_T only determines whether time_t is 32 or 64 bits; in the case of a 32-bit time_t the MSVCRT version determines whether you link against xxx() or xxx32(). (The define _TIME_T_IS_32BIT is redundant, it can be replaced by _USE_32BIT_TIME_T)

    typedef long __time32_t;
    
    // No real change from what exists in 
    // https://sourceforge.net/p/mingw/mingw-org-wsl/ci/master/tree/include/time.h
    // This is a linking issue, not a type definition issue
    #ifdef _USE_32BIT_TIME_T
      typedef __time32_t time_t;
      #define _TIME_T_IS_32BIT
    #else
      typedef __time64_t time_t
      #define _TIME_T_IS_64BIT
    #endif
    
    // New approach to link to the right library function in sys/utime.h
    #ifdef _TIME_T_IS_32BIT
      #if MSVCRT_VERSION < 800
        // prototype utime()
      #else
        // prototype utime32(), and inline utime() -> utime32()
      #endif
    #else /* if _TIME_T_IS_64BIT */
      // prototype utime64(), and inline utime() -> utime64()
    #endif
    

    Dealing specifically with sys/utime.h:

    _CRTIMP int __cdecl __MINGW_NOTHROW _utime64 (const char*, struct __utimbuf64*);
    _CRTIMP int __cdecl __MINGW_NOTHROW _wutime64 (const wchar_t*, struct __utimbuf64*);
    _CRTIMP int __cdecl __MINGW_NOTHROW _futime64 (int, struct __utimbuf64*);
    
    #if MSVCRT_VERSION < 800
    _CRTIMP int __cdecl __MINGW_NOTHROW _utime (const char*, struct __utimbuf*);
    _CRTIMP int __cdecl __MINGW_NOTHROW _wutime (const wchar_t*, struct __utimbuf*);
    _CRTIMP int __cdecl __MINGW_NOTHROW _futime (int, struct __utimbuf32*);
    #else
    _CRTIMP int __cdecl __MINGW_NOTHROW _utime32 (const char*, struct __utimbuf32*);
    _CRTIMP int __cdecl __MINGW_NOTHROW _wutime32 (const wchar_t*, struct __utimbuf32*);
    _CRTIMP int __cdecl __MINGW_NOTHROW _futime32 (int, struct __utimbuf32*);
    #endif
    
    #ifndef _USE_32BIT_TIME_T
    _CRTALIAS int __cdecl __MINGW_NOTHROW   _utime (const char* _v1, struct _utimbuf* _v2)  { return(_utime64 (_v1,(struct __utimbuf64*)_v2)); }
    _CRTALIAS int __cdecl __MINGW_NOTHROW   _wutime (const wchar_t* _v1, struct _utimbuf* _v2) { return(_wutime64 (_v1,(struct __utimbuf64*)_v2)); }
    _CRTALIAS int __cdecl __MINGW_NOTHROW   _futime (int _v1, struct _utimbuf* _v2) { return(_futime64 (_v1,(struct __utimbuf64*)_v2)); }
    #elif MSVCRT_VERSION >= 800
    _CRTALIAS int __cdecl __MINGW_NOTHROW   _utime (const char* _v1, struct _utimbuf* _v2)  { return(_utime32 (_v1,(struct __utimbuf32*)_v2)); }
    _CRTALIAS int __cdecl __MINGW_NOTHROW   _wutime (const wchar_t* _v1, struct _utimbuf* _v2) { return(_wutime32 (_v1,(struct __utimbuf32*)_v2)); }
    _CRTALIAS int __cdecl __MINGW_NOTHROW   _futime (int _v1, struct _utimbuf* _v2) { return(_futime32 (_v1,(struct __utimbuf32*)_v2)); }
    // #else = defined _USE_32BIT_TIME_T and MSVCRT_VERSION < 800
    // do nothing: _utime() and friends are already prototyped above
    #endif
    

    Earnie, as I understand it you can compile with _USE_32BIT_TIME_T defined using any version of MSVC (linking against any version of MSVCRT) and you will get a 32-bit time_t.

    If you don't have _USE_32BIT_TIME_T defined then compilers pre-MSVC-2005 will give you a 32-bit time_t by default (and I'm not aware of any header that will give you a 64-bit time_t when compiling a 32-bit app); compilers MSVC-2005 and later will give you a 64-bit time_t by default. MinGW already defaults to 64-bit time_t, so it would make sense to follow the MSVC-2005 approach.

    If you link against MSVCRT.DLL 7.0 or lower then there are no xxx32() functions, only xxx() and xxx64(). If you link against MSVCR80.DLL or higher then there are no xxx() functions, only xxx32() and xxx64(). You must specialise your prototypes and inline functions according to the target MSVCRT DLL, not the definition of time_t (which is determined only by _USE_32BIT_TIME_T irrespective of the target runtime DLL).

     
1 2 3 4 > >> (Page 1 of 4)