#5115 _USE_32BIT_TIME_T wrong for 32bit __MINGW32__

current: 8.5.14
closed-invalid
Jan Nijtmans
5
2014-08-14
2012-09-24
Earnie Boyd
No

The use of _USE_32BIT_TIME_T requires libmsvcr80.a and the MSVCR80.DLL. The MinGW.org team requires that distributions for software only require MSVCRT.DLL since this is the known system default. To resolve the issue I removed the define for this macro in win/tclWinPort.h to build the software.

Discussion

1 2 3 > >> (Page 1 of 3)
  • Jan Nijtmans
    Jan Nijtmans
    2012-09-24

    • assigned_to: nobody --> nijtmans
     
  • Jan Nijtmans
    Jan Nijtmans
    2012-09-24

    So, what's the problem?

     
  • Earnie Boyd
    Earnie Boyd
    2012-09-24

    The problem is that _USE_32BIT_TIME_T is the wrong solution for the original issue. It should not be used since this causes an dependency that cannot be guaranteed to be available. Perhaps a use of a configure time option of HAVE_LOCALTIME32 would be a better solution and a --with-localtime32 option be used with configure to set it.

     
  • Jan Nijtmans
    Jan Nijtmans
    2012-09-25

    Some questions:
    What Tcl version are you talking about? 8.5.?, 8.6.?

    >an dependency that cannot be guaranteed to be available
    A dependancy with what? Tcl compiles out-of-the-box on
    mingw, mingw_w64 and MSVC, without the need for
    a configuration option. _USE_32BIT_TIME_T is only
    set when BUILD_tcl is set, in tclWinPort.h which is
    not supposed to be used by extensions anyway.
    So, what's the problem?

     
  • Earnie Boyd
    Earnie Boyd
    2012-09-25

    I downloaded the latest package 8.5.12. I used the tcl package to test changes I am making to the MinGW.org mingwrt and w32api source before I distribute them.

    The problem is that _USE_32BIT_TIME_T is set explicitly in tclWinPort.h as delivered. The functions enabled by _USE_32BIT_TIME_T do not exist in the MSVCRT.DLL. _WIN64 doesn't have the functions at all so there is a guard to not define _USE_32BIT_TIME_T. _WIN32 has the functions but only in a non-standard DLL.

    The problem occurs during linking with ld complaining about unresolved symbols for __localtime32, __mktime32 and __gmtime32. They are unresolved because libmsvcrt.a does not contain the symbols. These symbols are used based on _USE_32BIT_TIME_T in include/time.h when we create an alias function of localtime, mktime and gmtime respectively.

    Now, with the current release of w32api this may not have been an issue because there were some extra nonsense (IMO) guards which prevented the use of these symbols even when _USE_32BIT_TIME_T was enabled. With MSVC it wouldn't cause an issue because the DLL used by it would contain these symbols. It is an issue now for MinGW.org because the current repository code, which will soon be released, has the extra guards removed and has exposed the issue. The issue is that MSVCRT.DLL does not contain the functions enabled by _USE_32BIT_TIME_T.

     
  • Jan Nijtmans
    Jan Nijtmans
    2012-09-25

    I'm sorry that this causes a regression in mingw, but the fact that it
    compiles fine in older mingw versions, in mingw_w64 and all msvc
    versions tell me that the problem is really in mingw.
    > It is an issue now for MinGW.org because the current repository
    > code, which will soon be released, has the extra guards removed and has
    > exposed the issue
    So, that's where the regression is. mingw shouln't redefine localtime
    to _localtime32 for msvcrt versions where this function doesn't
    exist, independant from the setting of _USE_32BIT_TIME_T.
    In older MSVC headers, _USE_32BIT_TIME_T didn't have
    any effect, so in the mingw headers for MSVCRT < 2005
    the setting of _USE_32BIT_TIME_T should not have any
    effect either. It's an incompatibility with MSVC < 2005

     
  • Earnie Boyd
    Earnie Boyd
    2012-09-25

    _USE_32BIT_TIME_T was designed as an after thought to resolve a legacy code compatibility issue. It should only be defined for those applications that require a time_t structure that is 32 bits. By default, time_t is 64 bits and only 64 bits time_t structure is provided by the default runtime.

    So if you define _USE_32BIT_TIME_T in your code you need to provide a library that supports the functions something like -lmsvcr80 but then the user must be aware that msvcr80.dll is required and it might not be since it isn't supplied by default.

    The changes I've made to the repository code isn't a regression the existing code was regressed already. The project specified _USE_32BIT_TIME_T but it was previously not used properly. With my changes the project specifying _USE_32BIT_TIME_T give the appropriate declarations and must also specify a library during the link that contains those functions. However, the linked application might not run due to dependencies on non-standard libraries.

    While mingw-w64 64bit compiled code will work since _USE_32BIT_TIME_T isn't defined in tclWinPort.h because _WIN64 is defined; the mingw-w64 32bit compiled code will give the same link time error since they have no means to guard based on the version of MSVCRT. The new code for MinGW.org _USE_32BIT_TIME_T is now more inline with that of mingw-w64 code.

    The resolution here is to define HAVE_32BIT_TIME_T when --with-32bit-time is specified and one of -lmsvcr80, -lmsvcr80d, -lmsvcr90, -lmsvcr90d, -lmsvcr100, -lmsvcr100d, -lmsvcr110 or -lmsvcr110d is found and the resulting binary works during configure. Then modify tclWinPort.h to filter the define for _USE_32BIT_TIME_T based on HAVE_32BIT_TIME_T.

    Since a 32bit time_t is an after thought and was given to help out legacy code and since 64bit time_t is the default it should be up to the users of the source to have it enabled or not during the configure process with disabled being the default to match the compilers.

     
  • Twylite
    Twylite
    2012-09-25

    "In versions of Visual C++ and Microsoft C/C++ before Visual C++ 2005, time_t was a long int (32 bits) and hence could not be used for dates past 3:14:07 January 19, 2038, UTC. In Visual C++ 2005, time_t is equivalent to __time64_t by default, but defining _USE_32BIT_TIME_T changes time_t to __time32_t and forces many time functions to call versions that take the 32-bit time_t." -- http://msdn.microsoft.com/en-us/library/w4ddyt9h\(v=vs.80).aspx

    This macro is required to force time_t to 32-bits (as expected by the Tcl sources in a 32-bit environment) when the compiler is MSVC2005 or later. Earlier versions of the compiler don't recognise the macro and safely ignore it.

    What you are saying is that the MinGW headers respect _USE_32BIT_TIME_T, but the libraries you link against don't. In other words you have a mismatch between the headers and the libraries. That is a problem in your development environment, not with Tcl.

    "Since a 32bit time_t is an after thought and was given to help out legacy
    code and since 64bit time_t is the default it should be up to the users of
    the source to have it enabled or not during the configure process with
    disabled being the default to match the compilers."

    The need for _USE_32BIT_TIME_T relates to assumptions in the Tcl sources about typecasting and time_t arithmetic in a 32-bit environment. The Tcl developers decide that, not the person compiling the software.

     
  • Earnie Boyd
    Earnie Boyd
    2012-09-25

    After further thought, study and the response from twylite, I have reworked the alias functions such that if _HAVE_32BIT_TIME_T is defined it will call the 32bit functions otherwise they will call the 64bit functions and do datatype typing as appropriate. The fortunate thing is that the tm structure is the same regardless of the call being used.

    Further inspection shows me that my Windows XP 32bit system doesn't contain the 32bit functions in msvcrt.dll but my Windows 7 SysWOW64/msvcrt.dll does.

    Do you have any test scripts or know of another tcl dependent package I can use to validate this with?

     
  • Earnie Boyd
    Earnie Boyd
    2012-09-25

    • status: open --> pending-invalid
     
1 2 3 > >> (Page 1 of 3)