weird behavior of msvcrt

Windows specific questions.
Post Reply
Mysoft
Posts: 829
Joined: Jul 28, 2005 13:56
Location: Brazil, Santa Catarina, Indaial (ouch!)
Contact:

weird behavior of msvcrt

Post by Mysoft »

so... code speaks for itself...

Code: Select all

#cmdline "-gen gcc -O 3"

#include "crt.bi"

var hCrt100 = DylibLoad("msvcr100.dll")
var hCrt = DylibLoad("msvcrt.dll")

dim as typeof(@sscanf) pfsscanf = DyLibSymbol(hCrt,"sscanf")

dim as typeof(@sscanf) pfsscanf100 = DyLibSymbol(hCrt100,"sscanf")

#if __Fb_Backend__ = "gcc" 
declare function fnsscanf cdecl alias "__builtin_sscanf" (byval as zstring ptr, byval as zstring ptr, ...) as long
#endif

dim as zstring*64 pzChar = "7" !"\178" "2"
'178 and 127 = '2'
print pzChar

dim as single fResu
dim as long iLen

print "---------- sscanf ----------"
sscanf( pzChar , "%f%n" ,@fResu,@iLen )
printf(!"%g %i\n",fResu,iLen)

if hCrt then
  print "---------- sscanf (dylib msvcrt.dll) ----------"
  pfsscanf( pzChar , "%f%n" ,@fResu,@iLen )
  printf(!"%g %i\n",fResu,iLen)
end if

if hCrt100 then
  print "---------- sscanf (dylib msvcr100.dll) ----------"
  pfsscanf100( pzChar , "%f%n" ,@fResu,@iLen )
  printf(!"%g %i\n",fResu,iLen)
end if

#ifdef fnsscanf
  print "---------- sscanf (built-in) ----------"
  fnsscanf( pzChar , "%f%n" ,@fResu,@iLen )
  printf(!"%g %i\n",fResu,iLen)
#endif

sleep
as output i get...

Code: Select all

7▓2
---------- sscanf ----------
7 3
---------- sscanf (dylib msvcrt.dll) ----------
7 3
---------- sscanf (dylib msvcr100.dll) ----------
7 1
---------- sscanf (built-in) ----------
7 3
tested on windows 7 (32bit)... compiling with/without -gen gcc does not change anything (except the built-in gcc one isnt testable)
it seems to only get triggered with \178 and \179 , and while it gets triggered with built-in and msvcrt one... it does not get triggered if i test this on C... which is VERY weird... (and at same time expected)

does everybody get the same behavior?
UEZ
Posts: 844
Joined: May 05, 2017 19:59
Location: Germany

Re: weird behavior of msvcrt

Post by UEZ »

Win10 x64 result for x86/x64

Code: Select all

7▓2
---------- sscanf ----------
7 3
---------- sscanf (dylib msvcrt.dll) ----------
7 3
---------- sscanf (dylib msvcr100.dll) ----------
7 1
---------- sscanf (built-in) ----------
7 3
which looks like the same as yours.
Mysoft
Posts: 829
Joined: Jul 28, 2005 13:56
Location: Brazil, Santa Catarina, Indaial (ouch!)
Contact:

Re: weird behavior of msvcrt

Post by Mysoft »

hum... i will try in NASM or FASM as well... so see if i get the same behavior calling the msvcrt.dll , and i will check if the GCC version is calliing msvcrt in the end... to confirm if the problem is with msvcrt.dll implementation of that, altough i dont see how the "built-in" implementation would not work (unless it just forward to the regular implementation, but in that case why it would work in C hehehe)

just to make it clear... all those results were suppose to be 7 1
adeyblue
Posts: 197
Joined: Nov 07, 2019 20:08

Re: weird behavior of msvcrt

Post by adeyblue »

It's probably the Locale setting, try this in your C compiler

Code: Select all

void CheckSScanF()
{
	//setlocale(LC_ALL, "");
	char* pLocale = setlocale(LC_ALL, NULL);
	printf("Locale: %s\n", pLocale);
	const char* pText = "7" "\xb2" "2";
	float fl = 0;
	int cnt = 0;
	int ret = sscanf(pText, "%f%n", &fl, &cnt);
	printf("Read fl='%g', cnt='%i', ret=%d\n", fl, cnt, ret);
}
If I leave it like this, it prints:
Locale: C
Read fl='7', cnt='1', ret=1

If I uncomment the top line (that setlocale is what an FB program does when it starts up)
Locale: English_United Kingdom.1252
Read fl='7', cnt='3', ret=1

You get different behaviour in your example as FBs setlocale only affects the CRT it links to (msvcrt), while the locale in msvcr100 hasn't been changed and it defaults to the C locale.
msvcrt is the one FB uses by default so the normal and dylib msvcrt sscanfs are the same one. __builtin_sscanf (at least in the combination of your example code and my install of Freebasic) just calls that one too, so all three of those are the same.

cnt is 3 in code page 1252 as 0xb2 is a superscript 2, so it counts as a digit that scanf reads while parsing the float. In code page 850 (which I think is the default C one) it's an accented e, which doesn't.
Mysoft
Posts: 829
Joined: Jul 28, 2005 13:56
Location: Brazil, Santa Catarina, Indaial (ouch!)
Contact:

Re: weird behavior of msvcrt

Post by Mysoft »

adeyblue wrote: Jun 24, 2022 20:30 cnt is 3 in code page 1252 as 0xb2 is a superscript 2, so it counts as a digit that scanf reads while parsing the float. In code page 850 (which I think is the default C one) it's an accented e, which doesn't.
yeah, you're probabily right... i even had see the ² on C (while on freebasic it shows the CP-850 symbol indeed) but that wouldnt ring me a bell that sscanf would parse that as part of a float... as i never have seen any documentation about which symbols scanf would process on that, have you?
Mysoft
Posts: 829
Joined: Jul 28, 2005 13:56
Location: Brazil, Santa Catarina, Indaial (ouch!)
Contact:

Re: weird behavior of msvcrt

Post by Mysoft »

also on that note... seems the locale.bi constants for LC_* are wrong on windows...

because mingw have LC_ALL as 0
while freebasic one have LC_ALL as 6

so the call to SetLocale to set something different than the 1252 (that is default on my system it seems) was failing as well :)
Post Reply