Re: [Mingw-w64-public] errno not set by bad call to strtof()
在 2020/1/8 上午6:53, David Mathog 写道: > Am I using errno improperly for mingw64 (maybe some Windows variant is > needed instead?) or is there some other issue in play? > It seems like a bug. `strtodf()` is implemented in 'mingw-w64-crt/stdio/strtof.c' which just calls `strtod()`. This is wrong for two reasons. One is that it doesn't handle overflows correctly as in your example. The other is that this suffers from double rounding errors (conversion from "0x0.817FFF" to `double` then casting the result to `float` yields a different result from a direct conversion). Perhaps this simple wrapper exists only because MSVCRT doesn't export `strtof()`. In my opinion we should forward to `__strtof()` instead which is defined in 'mingw-w64-crt/gdtoa/strtof.c'. -- Best regards, LH_Mouse signature.asc Description: OpenPGP digital signature ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] errno not set by bad call to strtof()
On 2020-01-08 11:12, David Mathog wrote: Searched around until the stdlib.h file was located and found within it that there was a define __USE_MINGW_STRTOX. So built like this: gcc -Wall -std=c99 -pedantic -D__USE_MINGW_STRTOX -o errno_prob errno_prob.c If this is used instead: gcc -Wall -std=c99 -pedantic -D__USE_MINGW_ANSI_STDIO -o errno_prob errno_prob.c not only does it also define __USE_MINGW_STRTOX but printf statements also emit "inf", "nan" and such instead of Microsoft's variants from the old msvcrtl. Not clear to me why "-std=c99" doesn't default to "-D__MUSE_MINGW_ANSI_STDIO" since supplying the c99 behavior seems to require the latter. Regards, David Mathog mat...@caltech.edu Manager, Sequence Analysis Facility, Biology Division, Caltech ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] errno not set by bad call to strtof()
try to load the symbol to bypass the mingw defines (LoadLibrary + GetProcAddress and call the symbol) also try without -std=c99 (and with -std=c89, as gcc sets itself by default to gnu11 or something like that, iirc) to see if it works. strtol always exists in Windows, whatever the standard is on Unix. Vincent On Wed, Jan 8, 2020 at 8:13 PM David Mathog wrote: > > On 2020-01-08 09:58, Vincent Torri wrote: > > the look at the official doc : > > https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strtof-strtof-l-wcstof-wcstof-l?view=vs-2019 > > > > as strtof is a function in msvcrt.dll, maybe it's a bug in the > > implementation. > > Stranger and stranger. It fails when compiled this way: > > gcc -Wall -std=c99 -pedantic -o errno_prob errno_prob.c > > However, it works when compiled this way: > > g++ -Wall -o errno_prob errno_prob.c > > The binary is still linked to msvcrt.dll (according to ntdll) but > perhaps in this mode > it calls its own function? > > Searched around until the stdlib.h file was located and found within it > that there was a define > __USE_MINGW_STRTOX. So built like this: > > gcc -Wall -std=c99 -pedantic -D__USE_MINGW_STRTOX -o errno_prob > errno_prob.c > > and strtof's errno works in both mingw32 (W7) and mingw64 (W10). > > However, beyond the defines in stdlib.h I have not found any > documentation about this. > Could one of the developers please chip in and tell us what is going on > here? > gcc is 9.2.0. > > Thanks, > > David Mathog > mat...@caltech.edu > Manager, Sequence Analysis Facility, Biology Division, Caltech > > > ___ > Mingw-w64-public mailing list > Mingw-w64-public@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/mingw-w64-public ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] errno not set by bad call to strtof()
On 2020-01-08 09:58, Vincent Torri wrote: the look at the official doc : https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strtof-strtof-l-wcstof-wcstof-l?view=vs-2019 as strtof is a function in msvcrt.dll, maybe it's a bug in the implementation. Stranger and stranger. It fails when compiled this way: gcc -Wall -std=c99 -pedantic -o errno_prob errno_prob.c However, it works when compiled this way: g++ -Wall -o errno_prob errno_prob.c The binary is still linked to msvcrt.dll (according to ntdll) but perhaps in this mode it calls its own function? Searched around until the stdlib.h file was located and found within it that there was a define __USE_MINGW_STRTOX. So built like this: gcc -Wall -std=c99 -pedantic -D__USE_MINGW_STRTOX -o errno_prob errno_prob.c and strtof's errno works in both mingw32 (W7) and mingw64 (W10). However, beyond the defines in stdlib.h I have not found any documentation about this. Could one of the developers please chip in and tell us what is going on here? gcc is 9.2.0. Thanks, David Mathog mat...@caltech.edu Manager, Sequence Analysis Facility, Biology Division, Caltech ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] errno not set by bad call to strtof()
On 2020-01-08 09:58, Vincent Torri wrote: the look at the official doc : https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strtof-strtof-l-wcstof-wcstof-l?view=vs-2019 as strtof is a function in msvcrt.dll, maybe it's a bug in the implementation. Could be, but one might have thought MS would have seen and fixed this long ago. Here are all tests so far linux:DEBUG buffer 0x7ffdb3ad8ee0 final 0x7ffdb3ad8ee6 fv inf errno 34 mingw64 (W10,64): DEBUG buffer 0068F970 final 0068F977 fv 1.#INF00 errno 0 mingw32 (W7,32): DEBUG buffer 009F2FD8 final 009F2FDF fv 1.#INF00 errno 0 mingw32 (XP,32): DEBUG buffer 003e2470 final 003e2477 fv inf errno 34 The last one was from a really old version of msys, circa 2012. When these lines were added to the test program: errno=0; FILE *fp = fopen("this will not work","r"); fprintf(stderr,"DEBUG fp %p errno %d\n",(void *)fp, errno); fflush(stderr); all platforms correctly emitted: DEBUG fp (nil) errno 2 So it isn't a general errno issue, it seems to be specific to strtof (and possibly related functions). Are these maybe wrapped up some way by mingw before msvcrt.dll is actually called? That might explain how errno gets lost. Thanks, David Mathog mat...@caltech.edu Manager, Sequence Analysis Facility, Biology Division, Caltech ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] errno not set by bad call to strtof()
the look at the official doc : https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/strtof-strtof-l-wcstof-wcstof-l?view=vs-2019 as strtof is a function in msvcrt.dll, maybe it's a bug in the implementation. Vincent Torri On Wed, Jan 8, 2020 at 6:50 PM David Mathog wrote: > > On 2020-01-07 20:40, Vincent Torri wrote: > > hello > > > > have you looked at the exemple at the bottom of that page : > > > > https://linux.die.net/man/3/strtol > > Sure. My code works on linux using gnu compilers but does not work in > mingw64 using > (more or less) the same compilers and the results differ. Below is a a > tiny complete test program which demonstrates the issue showing the > issue, just cut and paste the indicated region into a bash shell on > linux and mingw64 > > #start cut here > cat >errno_prob.c <<'EOD' > /* > Build with: > > gcc -Wall -std=c99 -pedantic -o errno_prob errno_prob.c > > Run with > > errno_prob "1.0e+40" #overflow test > > */ > > #include > #include > #include > > > int main(int argc,char **argv){ > char *final; > errno=0; > float fv = strtof(argv[1],&final); > fprintf(stderr,"DEBUG buffer %p final %p fv %f errno > %d\n",argv[1],final,fv, errno); > fflush(stderr); > exit(EXIT_SUCCESS); > } > EOD > gcc -Wall -std=c99 -pedantic -o errno_prob errno_prob.c > ./errno_prob "1.0e+40" > #end cut here > > Outputs from the two systems: > > linux: DEBUG buffer 0x7ffdb3ad8ee0 final 0x7ffdb3ad8ee6 fv inf errno > 34 > mingw64: DEBUG buffer 0068F970 final 0068F977 fv > 1.#INF00 errno 0 > > The only significant difference is that errno is not set in the mingw64 > one. It should be though, because 1.0e+40 is an ERANGE state, as > correctly indicated on linux. > No input I tried would make errno something other than 0. These were > tried: > > 1.0e+40 > blech > .001 > 1000 > 1.0e-100 > > So why is errno not set in mingw64? > > Thanks, > > David Mathog > mat...@caltech.edu > Manager, Sequence Analysis Facility, Biology Division, Caltech > > > ___ > Mingw-w64-public mailing list > Mingw-w64-public@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/mingw-w64-public ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] errno not set by bad call to strtof()
On 2020-01-07 20:40, Vincent Torri wrote: hello have you looked at the exemple at the bottom of that page : https://linux.die.net/man/3/strtol Sure. My code works on linux using gnu compilers but does not work in mingw64 using (more or less) the same compilers and the results differ. Below is a a tiny complete test program which demonstrates the issue showing the issue, just cut and paste the indicated region into a bash shell on linux and mingw64 #start cut here cat >errno_prob.c <<'EOD' /* Build with: gcc -Wall -std=c99 -pedantic -o errno_prob errno_prob.c Run with errno_prob "1.0e+40" #overflow test */ #include #include #include int main(int argc,char **argv){ char *final; errno=0; float fv = strtof(argv[1],&final); fprintf(stderr,"DEBUG buffer %p final %p fv %f errno %d\n",argv[1],final,fv, errno); fflush(stderr); exit(EXIT_SUCCESS); } EOD gcc -Wall -std=c99 -pedantic -o errno_prob errno_prob.c ./errno_prob "1.0e+40" #end cut here Outputs from the two systems: linux: DEBUG buffer 0x7ffdb3ad8ee0 final 0x7ffdb3ad8ee6 fv inf errno 34 mingw64: DEBUG buffer 0068F970 final 0068F977 fv 1.#INF00 errno 0 The only significant difference is that errno is not set in the mingw64 one. It should be though, because 1.0e+40 is an ERANGE state, as correctly indicated on linux. No input I tried would make errno something other than 0. These were tried: 1.0e+40 blech .001 1000 1.0e-100 So why is errno not set in mingw64? Thanks, David Mathog mat...@caltech.edu Manager, Sequence Analysis Facility, Biology Division, Caltech ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] errno not set by bad call to strtof()
hello have you looked at the exemple at the bottom of that page : https://linux.die.net/man/3/strtol ? Vincent Torri On Tue, Jan 7, 2020 at 11:54 PM David Mathog wrote: > > A program of mine "binload" which has key parts: > > #include > #include > #include > #include > #include > #include > #include/* for uint8_t*/ > #include /* for PRId64 */ > #include > #include/* for close */ > #include > > int main(int argc,char **argv){ > errno = 0; /* Works around an issue with OpenMPI preload which can > leaver errno set */ > > float fv; > char buffer[1024]; > char *final; > > /* code that reads a line of text and puts it into buffer */ > > fv = strtof(buffer,&final); > fprintf(stderr,"DEBUG buffer %p final %p fv %f errno > %d\n",buffer,final,fv, errno);fflush(stderr); > > is compiled on mingw64 with: > > gcc -o binload binload.c > > When the strtof() function runs with buffer containing the string > "1.0e+40" it fails, as it should, > because the value is too large for a float. On linux errno is set and > later code handles the error. However in mingw64 that debug line emits: > > DEBUG buffer 0068F970 final 0068F977 fv 1.#INF00 errno 0 > > Because errno is not set the error isn't handled correctly. If the > formatted float in "buffer" is > within range then strtof() returns the correct value. For instace, for > 1.0e+04 it emits: > > DEBUG buffer 0068F970 final 0068F977 fv 1.00 > errno 0 > > Am I using errno improperly for mingw64 (maybe some Windows variant is > needed instead?) or is there some other issue in play? > > Thanks, > > David Mathog > mat...@caltech.edu > Manager, Sequence Analysis Facility, Biology Division, Caltech > > > ___ > Mingw-w64-public mailing list > Mingw-w64-public@lists.sourceforge.net > https://lists.sourceforge.net/lists/listinfo/mingw-w64-public ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
Re: [Mingw-w64-public] errno not set by bad call to strtof()
On 2020-01-07 14:53, David Mathog wrote: is compiled on mingw64 with: gcc -o binload binload.c correction, that should have been: gcc -Wall -std=c99 -o binload binload.c strtof() is supposed to be defined for -std=c99. Regards, David Mathog mat...@caltech.edu Manager, Sequence Analysis Facility, Biology Division, Caltech ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public
[Mingw-w64-public] errno not set by bad call to strtof()
A program of mine "binload" which has key parts: #include #include #include #include #include #include #include/* for uint8_t*/ #include /* for PRId64 */ #include #include/* for close */ #include int main(int argc,char **argv){ errno = 0; /* Works around an issue with OpenMPI preload which can leaver errno set */ float fv; char buffer[1024]; char *final; /* code that reads a line of text and puts it into buffer */ fv = strtof(buffer,&final); fprintf(stderr,"DEBUG buffer %p final %p fv %f errno %d\n",buffer,final,fv, errno);fflush(stderr); is compiled on mingw64 with: gcc -o binload binload.c When the strtof() function runs with buffer containing the string "1.0e+40" it fails, as it should, because the value is too large for a float. On linux errno is set and later code handles the error. However in mingw64 that debug line emits: DEBUG buffer 0068F970 final 0068F977 fv 1.#INF00 errno 0 Because errno is not set the error isn't handled correctly. If the formatted float in "buffer" is within range then strtof() returns the correct value. For instace, for 1.0e+04 it emits: DEBUG buffer 0068F970 final 0068F977 fv 1.00 errno 0 Am I using errno improperly for mingw64 (maybe some Windows variant is needed instead?) or is there some other issue in play? Thanks, David Mathog mat...@caltech.edu Manager, Sequence Analysis Facility, Biology Division, Caltech ___ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public