Open yumetodo opened 5 years ago
You should ask it on mingw mailing list.
Here's what I get on my machine
$ cat strtod.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main(void)
{
char *s = "123456789012345678901234567890";
char *endp;
double x;
errno = 0;
x = strtod(s, &endp);
if (errno) {
perror("strtod");
exit(EXIT_FAILURE);
}
printf("input: %s\noutput: %.2f\nendptr: %zu\n",
s, x, strlen(endp));
exit(EXIT_SUCCESS);
}
$ gcc -v
Using built-in specs.
COLLECT_GCC=C:\MinGW\bin\gcc.exe
COLLECT_LTO_WRAPPER=c:/mingw/bin/../libexec/gcc/mingw32/8.2.0/lto-wrapper.exe
Target: mingw32
Configured with: ../src/gcc-8.2.0/configure --build=x86_64-pc-linux-gnu --host=mingw32 --target=mingw32 --pref ix=/mingw --disable-win32-registry --with-arch=i586 --with-tune=generic --enable-languages=c,c++,objc,obj-c++, fortran,ada --with-pkgversion='MinGW.org GCC-8.2.0-3' --with-gmp=/mingw --with-mpfr=/mingw --with-mpc=/mingw - -enable-static --enable-shared --enable-threads --with-dwarf2 --disable-sjlj-exceptions --enable-version-speci fic-runtime-libs --with-libiconv-prefix=/mingw --with-libintl-prefix=/mingw --enable-libstdcxx-debug --with-is l=/mingw --enable-libgomp --disable-libvtv --enable-nls --disable-build-format-warnings
Thread model: win32
gcc version 8.2.0 (MinGW.org GCC-8.2.0-3)
$ gcc -Wall -Wextra -pedantic -ansi -Og strtod.c -o strtod.exe
$ ./strtod.exe
input: 123456789012345678901234567890
output: 123456789012345677877719597056.00
endptr: 0
$ echo $?
0
$ ldd strtod.exe
ntdll.dll => /c/Windows/SYSTEM32/ntdll.dll (0x77660000)
??? => ??? (0x77820000)
wow64.dll => /c/Windows/SYSTEM32/wow64.dll (0x73ac0000)
wow64win.dll => /c/Windows/SYSTEM32/wow64win.dll (0x73a60000)
wow64cpu.dll => /c/Windows/SYSTEM32/wow64cpu.dll (0x73a50000)
$
So the problem seems to be gone?
$cat main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main(void)
{
char *s = "123456789012345678901234567890";
char *endp;
double x;
errno = 0;
x = strtod(s, &endp);
if (errno) {
perror("strtod");
exit(EXIT_FAILURE);
}
printf("input: %s\noutput: %.2f\nendptr: %d\n",
s, x, (int)strlen(endp));
exit(EXIT_SUCCESS);
}
$gcc -v
Using built-in specs.
COLLECT_GCC=C:\msys64\mingw64\bin\gcc.exe
COLLECT_LTO_WRAPPER=C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/9.3.0/lto-wrapper.exe
Target: x86_64-w64-mingw32
Configured with: ../gcc-9.3.0/configure --prefix=/mingw64 --with-local-prefix=/mingw64/local --build=x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --target=x86_64-w64-mingw32 --with-native-system-header-dir=/mingw64/x86_64-w64-mingw32/include --libexecdir=/mingw64/lib --enable-bootstrap --with-arch=x86-64 --with-tune=generic --enable-languages=c,lto,c++,fortran,ada,objc,obj-c++ --enable-shared --enable-static --enable-libatomic --enable-threads=posix --enable-graphite --enable-fully-dynamic-string --enable-libstdcxx-filesystem-ts=yes --enable-libstdcxx-time=yes --disable-libstdcxx-pch --disable-libstdcxx-debug --disable-isl-version-check --enable-lto --enable-libgomp --disable-multilib --enable-checking=release --disable-rpath --disable-win32-registry --disable-nls --disable-werror --disable-symvers --enable-plugin --with-libiconv --with-system-zlib --with-gmp=/mingw64 --with-mpfr=/mingw64 --with-mpc=/mingw64 --with-isl=/mingw64 --with-pkgversion='Rev2, Built by MSYS2 project' --with-bugurl=https://sourceforge.net/projects/msys2 --with-gnu-as --with-gnu-ld
Thread model: posix
gcc version 9.3.0 (Rev2, Built by MSYS2 project)
$gcc main.c -o main.exe -std=c11 -Wall -Wextra -pedantic
$./main.exe
input: 123456789012345678901234567890
output: 123456789012345680000000000000.00
endptr: 0
$ldd main.exe
ntdll.dll => /c/WINDOWS/SYSTEM32/ntdll.dll (0x7ff88c840000)
KERNEL32.DLL => /c/WINDOWS/System32/KERNEL32.DLL (0x7ff88ac60000)
KERNELBASE.dll => /c/WINDOWS/System32/KERNELBASE.dll (0x7ff889ff0000)
msvcrt.dll => /c/WINDOWS/System32/msvcrt.dll (0x7ff88c6b0000)
not fixed.
I wrote such two programs below.
C
versionC++
versionLook at
std::cin >> d;
. According to C++17 standard(N4659),operator >>
callstd::num_get<char>::do_get()
. Also, C++ standard saysIn other words,
std::cin >> d
call strtod.So, these two program (
C
version andC++
version) must be same behavior, I think,Now, I compile these programs on msys2 mingw64
C
version:gcc -std=c99 -Wall -Wextra -o a.exe a.c
C++
version:g++ -std=c++14 -Wall -Wextra -o b.exe b.cpp
And I execute these and the output is shown below:
C
version outputC++
version outputDifferent output was occered.
C
version output means thatstrtod
parse only 17 charactors and rest was skiped until non-digit charactor found.Now, I tried to compile these two programs on Visual Studio 2017
cl.exe
(_MSC_FULL_VER
==191627026
)I wrote cmake config like below:
Then,
And the outpt is
On msvc, these two programs output is same.
Also, On Linux, I test it.
C
version: https://wandbox.org/permlink/CF5uMprGgZs0Hdr6C++
verison: https://wandbox.org/permlink/OPKiFoAXNaLRNd4ithese two programs output is same.
Why only the binary compiled by mingw gcc (or mingw clang) output is strange? To investigate, I use
ldd
.The binary compiled by mingw gcc use
msvcrt
. On the other hand, the binary compiled by msvc useucrtbased
.About
msvcrt
anducrtbased
, I found document below:Visual C++ change history 2003 - 2015 | Microsoft Docs
So, the strange behavior was cased by
msvcrt
.However, Look at
C++
version on mingw gcc ouput again:These two program behavior should be same, however, actually, not.
C++ version parse input correctly.
Why doesn't affect
msvcrt
to C++ version?Is there any workarond to use
strtod
on mingw gcc correctly?