compiling Olthink

Discussion of chess software programming and technical issues.

Moderators: hgm, Rebel, chrisw, Ras, hgm, chrisw, Rebel, Ras

Quaaij
Posts: 2
Joined: Sun Dec 01, 2024 3:36 pm
Full name: Jan de Quaaij

compiling Olthink

Post by Quaaij »

Olithink is a great engine with great code.
However, when i tried to compile the code using visual c++ i ran in to problems.
the line:

low = free & (-free); // Lowest bit

does not compile. All the mentioned variabeles are bitboards, so unsigend 64bits words. That means that -free is not possible.

Can anybody tell me how to fix this problem?
And furthermore, did anybody else try compile Olithink using virtual c?
And if so, how did you do that?

thanks in advance,
mar
Posts: 2625
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: compiling Olthink

Post by mar »

you can try

Code: Select all

low = free & (0-free);
User avatar
Ras
Posts: 2668
Joined: Tue Aug 30, 2016 8:19 pm
Full name: Rasmus Althoff

Re: compiling Olthink

Post by Ras »

Or a clean solution, since the 2's complement is intended here, but not explicitely defined in older standards:

Code: Select all

low = free & (~free + 1);
Rasmus Althoff
https://www.ct800.net
mar
Posts: 2625
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: compiling Olthink

Post by mar »

how is that cleaner? "the intended" here is to isolate lsbit mask, not to obfuscate the code
"0-" is both shorter, in line with the original code and also works no matter if the target machine
uses 2's complement for negative integers or not
and of course any decent optimizing compiler will produce the same code for both
User avatar
Ras
Posts: 2668
Joined: Tue Aug 30, 2016 8:19 pm
Full name: Rasmus Althoff

Re: compiling Olthink

Post by Ras »

mar wrote: Mon Dec 02, 2024 7:10 am"0-" is both shorter, in line with the original code and also works no matter if the target machine uses 2's complement for negative integers or not
Yes, you are right.
Rasmus Althoff
https://www.ct800.net
petero2
Posts: 711
Joined: Mon Apr 19, 2010 7:07 pm
Location: Sweden
Full name: Peter Osterlund

Re: compiling Olthink

Post by petero2 »

It seems to me that the compiler is broken. All standard C/C++ specifications I have checked say something like this:
A computation involving unsigned operands can never overflow, because a result that cannot be represented by the resulting unsigned integer type is reduced modulo the number that is one greater than the largest value that can be represented by the resulting type.
The C++ standard additionally said this already in a 1995 draft version:
The negative of an unsigned quantity is computed by subtracting its value from 2^n, where n is the number of bits in the promoted operand.
mar
Posts: 2625
Joined: Fri Nov 26, 2010 2:00 pm
Location: Czech Republic
Full name: Martin Sedlak

Re: compiling Olthink

Post by mar »

I can't reproduce OP's problems compiling Olithink with either vs2022 or vs2017
Quaaij
Posts: 2
Joined: Sun Dec 01, 2024 3:36 pm
Full name: Jan de Quaaij

Re: compiling Olthink

Post by Quaaij »

Thanks for trying!

When i compile this line i get error c4146: unary minus operator applied to unsigned typ result still unsinged.

I have changed to another method to isolate the least significant bit, when in run the code in debug mode x64, the search() function triggers an error since variable 'w' is unintiatized. That happens in the lines following

int firstPvNode = first = NO_MOVE && pvnode;

I dont why this all happens, but it results in Olithink missing mate in one moves. In a certain position the engine needs a four ply search to find out that his opponent can mate in the second move. The engine can do various moves to prevent this mating move, but does not see this.
User avatar
Ras
Posts: 2668
Joined: Tue Aug 30, 2016 8:19 pm
Full name: Rasmus Althoff

Re: compiling Olthink

Post by Ras »

Quaaij wrote: Mon Dec 02, 2024 8:43 pmWhen i compile this line i get error c4146: unary minus operator applied to unsigned typ result still unsinged.
According to MS, C4146 is a warning, not an error, see https://learn.microsoft.com/en-us/cpp/e ... w=msvc-170. If that comes out as error on your end, maybe you have set your IDE to treat warnings as errors, so just deactivate that.
the search() function triggers an error since variable 'w' is unintiatized.
That's because w is only initialised in paths where it is needed, but it can be difficult for the compiler to keep track of that. Or maybe there actually is a path where w is read uninitialised. Try initialising that in search() and see what happens.
Current code:
int search(u64 ch, int c, int d, int ply, int alpha, int beta, int null, Move sem) {
int i, j, n, w, oc = c^1, pvnode = beta > alpha + 1;
Modification:
int search(u64 ch, int c, int d, int ply, int alpha, int beta, int null, Move sem) {
int i, j, n, w = alpha, oc = c^1, pvnode = beta > alpha + 1;
Rasmus Althoff
https://www.ct800.net
petero2
Posts: 711
Joined: Mon Apr 19, 2010 7:07 pm
Location: Sweden
Full name: Peter Osterlund

Re: compiling Olthink

Post by petero2 »

Quaaij wrote: Mon Dec 02, 2024 8:43 pm Thanks for trying!

When i compile this line i get error c4146: unary minus operator applied to unsigned typ result still unsinged.
This is a bug in Visual Studio, see https://developercommunity.visualstudio ... ror/287098
Maybe there is an update for your Visual Studio version that fixes the bug.
Quaaij wrote: Mon Dec 02, 2024 8:43 pm when in run the code in debug mode x64, the search() function triggers an error since variable 'w' is unintiatized. That happens in the lines following

int firstPvNode = first = NO_MOVE && pvnode;

I dont why this all happens
This is a bug in OliThink. Technically it is undefined behavior to use an uninitialized variable, and Visual Studio apparently detects this in debug mode. It is unlikely that this would be a problem in release mode though, because the "ext < 0" condition is always false when w is uninitialized. Here is a fix though that should make debug builds work:

Code: Select all

@@ -1008,7 +1008,7 @@ int search(u64 ch, int c, int d, int ply, int alpha, int beta, int null, Move se
 
 			int firstPVNode = first == NO_MOVE && pvnode;
 			if (!firstPVNode) w = -search(nch, oc, nd+ext, ply+1, -alpha-1, -alpha, 1, 0);
-			if (w > alpha && ext < 0) w = -search(nch, oc, nd, ply+1, -alpha-1, -alpha, 1, 0);
+			if (ext < 0 && w > alpha) w = -search(nch, oc, nd, ply+1, -alpha-1, -alpha, 1, 0);
 			if ((w > alpha && w < beta) || firstPVNode) w = -search(nch, oc, nd, ply+1, -beta, -alpha, 0, 0);
 
 			undoMove(0, c); memcpy(&P, &pos, sizeof(Pos));