int's mixing with __int64's in argument list not working?

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw

G.B. Harms
Posts: 42
Joined: Sat Aug 08, 2009 2:18 pm
Location: Almere

Re: int's mixing with __int64's in argument list not working

Post by G.B. Harms »

wgarvin wrote:Well for one thing, some of the snprintf format specifiers are wrong on 32-bit platforms... you pass __int64 parameters like node_count but give it a format specifier of %d
Not %d but %ld but that is also wrong.. should have been %llu and then it works fine. So you're right, Thanks!
G.B. Harms
Posts: 42
Joined: Sat Aug 08, 2009 2:18 pm
Location: Almere

Re: int's mixing with __int64's in argument list not working

Post by G.B. Harms »

Dann Corbit wrote:Is your program open source?
Yes.

https://github.com/Bobcat
wgarvin
Posts: 838
Joined: Thu Jul 05, 2007 5:03 pm
Location: British Columbia, Canada

Re: int's mixing with __int64's in argument list not working

Post by wgarvin »

G.B. Harms wrote:
wgarvin wrote:Well for one thing, some of the snprintf format specifiers are wrong on 32-bit platforms... you pass __int64 parameters like node_count but give it a format specifier of %d
Not %d but %ld but that is also wrong.. should have been %llu and then it works fine. So you're right, Thanks!
I think %d or %i is for a signed int, and %u is for an unsigned int. Those are all 32-bits on this platform.

Similarly %ld / %li and %lu are for "signed long" and "unsigned long" which also happen to be 32-bits on this platform.

Now I guess they have added %lld / %lli and %llu for "signed long long" and "unsigned long long" (which some compilers also know as "signed __int64" and "unsigned __int64"). Those ones are 64-bits on this platform.

In the interests of portability, its a good idea to always try and use the correct format specifiers for anything not smaller than an int. Otherwise you can end up with code that works fine on one compiler or platform, and crashes or misbehaves on a different compiler or platform. As you found out. :P
G.B. Harms
Posts: 42
Joined: Sat Aug 08, 2009 2:18 pm
Location: Almere

Re: int's mixing with __int64's in argument list not working

Post by G.B. Harms »

wgarvin wrote:
G.B. Harms wrote:
wgarvin wrote:Well for one thing, some of the snprintf format specifiers are wrong on 32-bit platforms... you pass __int64 parameters like node_count but give it a format specifier of %d
Not %d but %ld but that is also wrong.. should have been %llu and then it works fine. So you're right, Thanks!
I think %d or %i is for a signed int, and %u is for an unsigned int. Those are all 32-bits on this platform.

Similarly %ld / %li and %lu are for "signed long" and "unsigned long" which also happen to be 32-bits on this platform.

Now I guess they have added %lld / %lli and %llu for "signed long long" and "unsigned long long" (which some compilers also know as "signed __int64" and "unsigned __int64"). Those ones are 64-bits on this platform.

In the interests of portability, its a good idea to always try and use the correct format specifiers for anything not smaller than an int. Otherwise you can end up with code that works fine on one compiler or platform, and crashes or misbehaves on a different compiler or platform. As you found out. :P
Hmm.. I'm in the process of removing all cout's in favor of printf's and snprintf's.. Perhaps that's the wrong way around.

But having both cout and (sn)printf in the same program looks certainly wrong to me.

I´ll stick with the (sn)printf for now and pay some more attention to the format specifiers from now on !
Dann Corbit
Posts: 12542
Joined: Wed Mar 08, 2006 8:57 pm
Location: Redmond, WA USA

Re: int's mixing with __int64's in argument list not working

Post by Dann Corbit »

G.B. Harms wrote:
Dann Corbit wrote:Is your program open source?
Yes.

https://github.com/Bobcat
Here is a tweaked version of your program compiled for 64 bits:
http://cap.connx.com/chess-engines/new- ... /bobcat.7z

The only changes of substance was the API for your LPTHREAD_START_ROUTINE function and also I turned off buffering for standard input (you had turned it off for standard output).

I made a few more data items const safe, and a few other meaningless twiddles.
G.B. Harms
Posts: 42
Joined: Sat Aug 08, 2009 2:18 pm
Location: Almere

Re: int's mixing with __int64's in argument list not working

Post by G.B. Harms »

Dann Corbit wrote:
G.B. Harms wrote:
Dann Corbit wrote:Is your program open source?
Yes.

https://github.com/Bobcat
Here is a tweaked version of your program compiled for 64 bits:
http://cap.connx.com/chess-engines/new- ... /bobcat.7z

The only changes of substance was the API for your LPTHREAD_START_ROUTINE function and also I turned off buffering for standard input (you had turned it off for standard output).

I made a few more data items const safe, and a few other meaningless twiddles.
Hi Dan,

I like most of your changes, thanks! Unfortunately you seem to use 'tabs as spaces' whereas I am so fond of my tabs :) So I cannot easily merge them in (I use WinMerge), but I will make the changes when I come across the codes.

I also ran your executable and could see it is consistently (but only 3%) slower than my own (non PGO) build, at least for perft(6). I don' t think it is in the code changes so was curious about the build settings but could not open the .sln with MSVC 2008 Express. I think you use 2010? Perhaps 2010 makes slightly slower code than 2008. I downloaded the 2010 Express edition some time ago but have not yet been able to make 64 bit builds with it. I remember 2008 Express out-of-the-box could not do that either but forgot how I got it to work for 64 bit builds.

Gunnar
Dann Corbit
Posts: 12542
Joined: Wed Mar 08, 2006 8:57 pm
Location: Redmond, WA USA

Re: int's mixing with __int64's in argument list not working

Post by Dann Corbit »

G.B. Harms wrote:
Dann Corbit wrote:
G.B. Harms wrote:
Dann Corbit wrote:Is your program open source?
Yes.

https://github.com/Bobcat
Here is a tweaked version of your program compiled for 64 bits:
http://cap.connx.com/chess-engines/new- ... /bobcat.7z

The only changes of substance was the API for your LPTHREAD_START_ROUTINE function and also I turned off buffering for standard input (you had turned it off for standard output).

I made a few more data items const safe, and a few other meaningless twiddles.
Hi Dan,

I like most of your changes, thanks! Unfortunately you seem to use 'tabs as spaces' whereas I am so fond of my tabs :) So I cannot easily merge them in (I use WinMerge), but I will make the changes when I come across the codes.

I also ran your executable and could see it is consistently (but only 3%) slower than my own (non PGO) build, at least for perft(6). I don' t think it is in the code changes so was curious about the build settings but could not open the .sln with MSVC 2008 Express. I think you use 2010? Perhaps 2010 makes slightly slower code than 2008. I downloaded the 2010 Express edition some time ago but have not yet been able to make 64 bit builds with it. I remember 2008 Express out-of-the-box could not do that either but forgot how I got it to work for 64 bit builds.

Gunnar
Not sure why mine is slower.
The binary I got from the git hub does not run on my machine, so you share something in common with Don Dailey (neither of your 64 bit binaries will run on my machine).

I could not even compile your code right out of the box, I had to make some changes so the compiler would accept it.
User avatar
sje
Posts: 4675
Joined: Mon Mar 13, 2006 7:43 pm

Re: int's mixing with __int64's in argument list not working

Post by sje »

Assuming no compiler bugs and no library bugs, there should never be bad actual parameter conversions as long as a routine signature appears prior to any invocation.

As noted by others, the problem is with the printf() format string. If scanf() were also being used, it too would produce bogus results for similar reasons.

The solution is to never use printf()/scanf() or their cousins, but to instead use C++ formatted streams for all the goodness of type safety.

Free and reliable C+ compilers have been available or years. I can't see anyone starting a new project using C when C++ can be had, or even using a C library routine inside of a C++ program.
rbarreira
Posts: 900
Joined: Tue Apr 27, 2010 3:48 pm

Re: int's mixing with __int64's in argument list not working

Post by rbarreira »

sje wrote: Free and reliable and bloated and incompatible C+ compilers have been available or years.
Fixed it for you :wink:
wgarvin
Posts: 838
Joined: Thu Jul 05, 2007 5:03 pm
Location: British Columbia, Canada

Re: int's mixing with __int64's in argument list not working

Post by wgarvin »

sje wrote:Assuming no compiler bugs and no library bugs, there should never be bad actual parameter conversions as long as a routine signature appears prior to any invocation.
That doesn't apply to the variable-arguments part of the arguments list. IIRC, bool, char and similar things smaller than an int get converted to an int, and floats get converted to double. Other than that its kind of up to the compiler. If your int type is 32-bits and you pass a 64-bit type like long long, its likely to be stored differently than if you pass an int. Both the function passing the argument and the function interpreting it through va_arg or whatever (i.e. sprintf), have to use the same type or at least use types with the same representation on this platform+compiler combo.

sje wrote:As noted by others, the problem is with the printf() format string. If scanf() were also being used, it too would produce bogus results for similar reasons.

The solution is to never use printf()/scanf() or their cousins, but to instead use C++ formatted streams for all the goodness of type safety.
It's a matter of taste. Personally I avoid the C++ stream IO stuff like the plague, finding printf/sprintf a lot easier to work with.

That's the great thing about C++ (well, not really!): Everyone has their own subset "flavor" of C++ that they know well.

Trapped inside of C++, and struggling to get out, are not one but *many* nice small languages. Too bad it doesn't have better support for DSLs or compile-time metaprogramming, or we might really be able to make something out of that flexibility. :lol: