|
From: Pete M. <mad...@mi...> - 2013-12-27 16:37:29
|
Hi folks,
I've been using mngw for years along with code::blocks.
I recently upgraded mingw and after doing that my application started
acting wonky.
I've been tracking down bugs here and there, but the latest is that
diffetime() appears to be broken.
Stepping through the app in gdb I watched to see reasonable values go
into difftime(t1, t2), but it always seems to return t1.
For example:
int snfLOGmgr::SecsSinceStartup() {
return (int) difftime(Timestamp(), StartupTime);
}
If StartupTime is 1388157426, and Timestamp() returns 1388157546,
difftime should return 120.
Instead it returns 1388157546!!
Has anybody else run into this? Googling for a solution or mention of
the problem has been useless.
THANKS!!
_M
--
Pete McNeil, President
MicroNeil Research Corporation
www.microneil.com
703.779.4909 x7010
twitter/codedweller
|
|
From: Keith M. <kei...@us...> - 2013-12-27 22:41:28
|
On 27/12/13 15:37, Pete McNeil wrote:
> I've been tracking down bugs here and there, but the latest is that
> diffetime() appears to be broken.
I wonder: are you, perhaps running into a __time64_t vs. __time32_t issue.
> Stepping through the app in gdb I watched to see reasonable values go
> into difftime(t1, t2), but it always seems to return t1.
When you build your application with MinGW, unless you specifically
arrange to use an alternative non-distributable runtime DLL, difftime()
is furnished by MSVCRT.DLL. Depending on the version of MSVCRT.DLL
which is present on your host, the actual difftime() called may be a
__time32_t implementation, (expecting your t1 and t2 to be 32-bit), or
(in newer MSVCRT.DLL) it may be a __time64_t implementation, (expecting
64-bit t1 and t2).
> For example:
>
> int snfLOGmgr::SecsSinceStartup() {
> return (int) difftime(Timestamp(), StartupTime);
> }
>
> If StartupTime is 1388157426, and Timestamp() returns 1388157546,
> difftime should return 120.
>
> Instead it returns 1388157546!!
I'd expect that, if you passed __time64_t t1 and t2 to a __time32_t
difftime() implementation. With MinGW runtimes prior to v4.0, all time
functions were assumed to be __time32_t implementations; v4.0 and later
now adopt the Microsoft convention of assuming __time64_t, unless you
define _USE_32BIT_TIME_T.
In my opinion, this _USE_32BIT_TIME_T kludge is utterly broken by
design; much better, I think, to explicitly call the explicitly typed
functions, (_difftime32() or _difftime64() in the present case), rather
than the ambiguous kludge dependent implicit function, (difftime()
here). To make this completely robust, and to maintain compatibility
with older hosts, it is also necessary to probe the actual version of
MSVCRT.DLL on the run time host, to ensure that the explicit function is
actually available, before calling it, otherwise falling back to the
older implicit name, assuming it then expects __time32_t semantics[*].
[*] Yes, you might reasonably expect that MinGW's implementation would
handle this in this robust fashion; unfortunately, Earnie has declined
to implement it so, preferring to simply mimic the (broken) Microsoft
inspired kludgy behaviour.
--
Regards,
Keith.
|
|
From: Keith M. <kei...@us...> - 2013-12-28 16:35:41
|
On 27/12/13 22:41, Keith Marshall wrote: > On 27/12/13 15:37, Pete McNeil wrote: >> I've been tracking down bugs here and there, but the latest is that >> diffetime() appears to be broken. > > I wonder: are you, perhaps running into a __time64_t vs. __time32_t issue. > >> Stepping through the app in gdb I watched to see reasonable values go >> into difftime(t1, t2), but it always seems to return t1. > > When you build your application with MinGW, unless you specifically > arrange to use an alternative non-distributable runtime DLL, difftime() > is furnished by MSVCRT.DLL. Depending on the version of MSVCRT.DLL > which is present on your host, the actual difftime() called may be a > __time32_t implementation, (expecting your t1 and t2 to be 32-bit), or > (in newer MSVCRT.DLL) it may be a __time64_t implementation, (expecting > 64-bit t1 and t2). Further follow up, with some experimentation, suggests that while this quote from http://msdn.microsoft.com/en-us/library/3wbd7281.aspx > difftime is an inline function that evaluates to either _difftime32 > or _difftime64 depending on whether _USE_32BIT_TIME_T is defined. may be true of the headers provided with recent versions of MSVC, it is not true of the difftime() exported by MSVCRT.DLL, (at least up to and including that on my Win7 VM); in this case, difftime() appears to be provided as a __time32_t implementation. Thus, the API declared for difftime(), in MinGW's wsl-4.0, is simply broken, since by default it assumes a __time64_t implementation, yet it directs the call to an actual implementation which is __time32_t. Bug report filed: https://sourceforge.net/p/mingw/bugs/2152/ -- Regards, Keith. |
|
From: Pete M. <mad...@mi...> - 2013-12-29 14:46:41
|
On 2013-12-28 11:35, Keith Marshall wrote: > I wonder: are you, perhaps running into a __time64_t vs. __time32_t issue. You appear to be on to something. In my 32 bit build I added the #define _USE_32BIT_TIME_T Testing the resulting executable on my Win7 Pro machine yielded better results. Based on the remainder of your analysis I'm concerned this won't play well in the wild. I look forward to a more robust solution re your bug report: https://sourceforge.net/p/mingw/bugs/2152/ Thanks very much! _M -- Pete McNeil, President MicroNeil Research Corporation www.microneil.com 703.779.4909 x7010 twitter/codedweller |