a cautionary tale about simple-looking macros

Discussion of chess software programming and technical issues.

Moderators: hgm, Harvey Williamson, bob

Forum rules
This textbox is used to restore diagrams posted with the [d] tag before the upgrade.
wgarvin
Posts: 838
Joined: Thu Jul 05, 2007 3:03 pm
Location: British Columbia, Canada

a cautionary tale about simple-looking macros

Post by wgarvin » Sun Jul 03, 2011 4:10 pm

To try and understand how Ippolit works, I have been reformatting it to make it readable (renaming things, grouping related functions in files, etc).

Anyone who has looked at the Ippolit code knows that it looks a bit machine-generated. In particular, there are parts which could only be the output of some kind of macro expander (probably the C preprocessor, though it could be other things as well). I came across a real gem of one of these, which I spent the last two hours translating back into something human-readable! So I will describe it here.

The code in question can be found in IPP_ENG.c around line 6169. It looks like this:

Code: Select all

  if ((tower_dynamics->flag & 128))
    {
      if (score > 0)
 {
    if (position_fixed.bitboard[enumerated_white_bright])
        score -= 20 * (((((((((((((A8) & 7) - ((position_fixed.black_king) & 7)) >= 0) ? (((A8) & 7) - ((pos....
     else
     score -= 20 * (((((((((((((A1) & 7) - ((position_fixed.black_king) & 7)) >= 0) ? (((A1) & 7) - ((pos....
   }
      else
   {
    if (position_fixed.bitboard[enumerated_black_bright])
        score += 20 * (((((((((((((A8) & 7) - ((position_fixed.white_king) & 7)) >= 0) ? (((A8) & 7) - ((pos....
     else
     score += 20 * (((((((((((((A1) & 7) - ((position_fixed.white_king) & 7)) >= 0) ? (((A1) & 7) - ((pos....
   }
    }
...Well actually, it only looks like that in a text editor that doesnt wrap lines. The full code is so long I'll put it in a separate reply. But just to give you an idea, its over 22KB of source code, and contains 5,162 parentheses characters. It also contains 168 usages of the ternary operator (x ? y : z).

More after the break.

wgarvin
Posts: 838
Joined: Thu Jul 05, 2007 3:03 pm
Location: British Columbia, Canada

Re: a cautionary tale about simple-looking macros

Post by wgarvin » Sun Jul 03, 2011 4:11 pm

Here's the full mess. From IPP_ENG.c around line 6169.

Code: Select all

  if ((tower_dynamics->flag & 128))
    {
      if (score > 0)
	{
	  if (position_fixed.bitboard[enumerated_white_bright])
	    score -= 20 * ((((((((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) >= ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))))) <= ((((((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) >= ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;)))))))) ? ((((((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) >= ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))))) &#58; ((((((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) >= ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;)))))))) + 10 * ((((((((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) <= ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))))) <= ((((((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) <= ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;)))))))) ? ((((((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) <= ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))))) &#58; ((((((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) <= ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))))));
	  else
	    score -= 20 * ((((((((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) >= ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))))) <= ((((((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) >= ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;)))))))) ? ((((((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) >= ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))))) &#58; ((((((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) >= ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;)))))))) + 10 * ((((((((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) <= ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))))) <= ((((((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) <= ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;)))))))) ? ((((((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) <= ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))))) &#58; ((((((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) <= ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))) ? ((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.black_king&#41; & 7&#41;)))) &#58; ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.black_king&#41; >> 3&#41;))))))));
	&#125;
      else
	&#123;
	  if &#40;position_fixed.bitboard&#91;enumerated_black_bright&#93;)
	    score += 20 * ((((((((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) >= ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))))) <= ((((((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) >= ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;)))))))) ? ((((((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) >= ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))))) &#58; ((((((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) >= ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;)))))))) + 10 * ((((((((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) <= ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))))) <= ((((((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) <= ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;)))))))) ? ((((((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) <= ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))))) &#58; ((((((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) <= ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))))));
	  else
	    score += 20 * ((((((((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) >= ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))))) <= ((((((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) >= ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;)))))))) ? ((((((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) >= ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))))) &#58; ((((((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) >= ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;)))))))) + 10 * ((((((((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) <= ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))))) <= ((((((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) <= ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;)))))))) ? ((((((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) <= ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;A1&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;A1&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))))) &#58; ((((((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) <= ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))) ? ((((((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) >= 0&#41; ? ((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;) &#58; -((&#40;H8&#41; & 7&#41; - (&#40;position_fixed.white_king&#41; & 7&#41;)))) &#58; ((((((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) >= 0&#41; ? ((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;) &#58; -((&#40;H8&#41; >> 3&#41; - (&#40;position_fixed.white_king&#41; >> 3&#41;))))))));
	&#125;
    &#125;

wgarvin
Posts: 838
Joined: Thu Jul 05, 2007 3:03 pm
Location: British Columbia, Canada

Re: a cautionary tale about simple-looking macros

Post by wgarvin » Sun Jul 03, 2011 4:12 pm

Okay, so what in the world does that code do?

Well, one thing it should do is convince programmers to be careful whenever they use min, max or abs macros!

Many compilers including Microsoft's, supply min(a,b) and max(a,b) as macros, something like this (from WinDef.h):

Code: Select all

#ifndef max
#define max&#40;a,b&#41;            ((&#40;a&#41; > &#40;b&#41;) ? &#40;a&#41; &#58; &#40;b&#41;)
#endif

#ifndef min
#define min&#40;a,b&#41;            ((&#40;a&#41; < &#40;b&#41;) ? &#40;a&#41; &#58; &#40;b&#41;)
#endif
It seems the authors of Ippolit were also using a macro for abs. And their min/max macros are slightly different from Microsoft's. Anyway, here's the form that was used in Ippolit:

Code: Select all

#define max&#40;a,b&#41;            ((&#40;a&#41; >= &#40;b&#41;) ? &#40;a&#41; &#58; &#40;b&#41;)

#define min&#40;a,b&#41;            ((&#40;a&#41; <= &#40;b&#41;) ? &#40;a&#41; &#58; &#40;b&#41;)

#define abs&#40;a&#41;              ((&#40;a&#41; >= 0&#41; ? &#40;a&#41; &#58; -&#40;a&#41;)
I started with the abs() calls, searching for >= 0 and extracting expressions and converting them to abs. Then max and min. Anyway, after a while I had something that looked like this:

Code: Select all

//inline int RankOf&#40;x&#41; &#123; return &#40;x >> 3&#41;; &#125;
//inline int FileOf&#40;x&#41; &#123; return &#40;x & 7&#41;; &#125;

    if (&#40;tower_dynamics->flag & 128&#41;)
    &#123;
        if &#40;score > 0&#41;
        &#123;
            int bkRank = &#40;position_fixed.black_king >> 3&#41;;
            int bkFile = &#40;position_fixed.black_king & 7&#41;;

            if &#40;position_fixed.bb&#91;eWhiteBright&#93;)
                score -= 20 * min&#40;max&#40;abs&#40;FileOf&#40;A8&#41; - bkFile&#41;, abs&#40;RankOf&#40;A8&#41; - bkRank&#41;), max&#40;abs&#40;FileOf&#40;H1&#41; - bkFile&#41;, abs&#40;RankOf&#40;H1&#41; - bkRank&#41;))
                       + 10 * min&#40;min&#40;abs&#40;FileOf&#40;A8&#41; - bkFile&#41;, abs&#40;RankOf&#40;A8&#41; - bkRank&#41;), min&#40;abs&#40;FileOf&#40;H1&#41; - bkFile&#41;, abs&#40;RankOf&#40;H1&#41; - bkRank&#41;));
            else
                score -= 20 * min&#40;max&#40;abs&#40;FileOf&#40;A1&#41; - bkFile&#41;, abs&#40;RankOf&#40;A1&#41; - bkRank&#41;), max&#40;abs&#40;FileOf&#40;H8&#41; - bkFile&#41;, abs&#40;RankOf&#40;H8&#41; - bkRank&#41;))
                       + 10 * min&#40;min&#40;abs&#40;FileOf&#40;A1&#41; - bkFile&#41;, abs&#40;RankOf&#40;A1&#41; - bkRank&#41;), min&#40;abs&#40;FileOf&#40;H8&#41; - bkFile&#41;, abs&#40;RankOf&#40;H8&#41; - bkRank&#41;));
        &#125;
        else
        &#123;
            int wkRank = &#40;position_fixed.white_king >> 3&#41;;
            int wkFile = &#40;position_fixed.white_king & 7&#41;;

            if &#40;position_fixed.bb&#91;eBlackBright&#93;)
                score += 20 * min&#40;max&#40;abs&#40;FileOf&#40;A8&#41; - wkFile&#41;, abs&#40;RankOf&#40;A8&#41; - wkRank&#41;), max&#40;abs&#40;FileOf&#40;H1&#41; - wkFile&#41;, abs&#40;RankOf&#40;H1&#41; - wkRank&#41;))
                       + 10 * min&#40;min&#40;abs&#40;FileOf&#40;A8&#41; - wkFile&#41;, abs&#40;RankOf&#40;A8&#41; - wkRank&#41;), min&#40;abs&#40;FileOf&#40;H1&#41; - wkFile&#41;, abs&#40;RankOf&#40;H1&#41; - wkRank&#41;));
            else
                score += 20 * min&#40;max&#40;abs&#40;FileOf&#40;A1&#41; - wkFile&#41;, abs&#40;RankOf&#40;A1&#41; - wkRank&#41;), max&#40;abs&#40;FileOf&#40;H8&#41; - wkFile&#41;, abs&#40;RankOf&#40;H8&#41; - wkRank&#41;))
                       + 10 * min&#40;min&#40;abs&#40;FileOf&#40;A1&#41; - wkFile&#41;, abs&#40;RankOf&#40;A1&#41; - wkRank&#41;), min&#40;abs&#40;FileOf&#40;H8&#41; - wkFile&#41;, abs&#40;RankOf&#40;H8&#41; - wkRank&#41;));
        &#125;
    &#125;
That's still a little unwieldly, so I pulled out the abs() expressions to produce this version:

Code: Select all

//inline int RankOf&#40;x&#41; &#123; return &#40;x >> 3&#41;; &#125;
//inline int FileOf&#40;x&#41; &#123; return &#40;x & 7&#41;; &#125;

    if (&#40;tower_dynamics->flag & 128&#41;)
    &#123;
        if &#40;score > 0&#41;
        &#123;
			int bkRank = &#40;position_fixed.black_king >> 3&#41;;
			int bkFile = &#40;position_fixed.black_king & 7&#41;;
			int bkRanksFrom1 = abs&#40;RANK_1 - bkRank&#41;;
			int bkRanksFrom8 = abs&#40;RANK_8 - bkRank&#41;;
			int bkFilesFromA = abs&#40;FILE_A - bkFile&#41;;
			int bkFilesFromH = abs&#40;FILE_H - bkFile&#41;;
			
            if &#40;position_fixed.bb&#91;eWhiteBright&#93;)
                score -= 20 * min&#40;max&#40;bkFilesFromA, bkRanksFrom8&#41;, max&#40;bkFilesFromH, bkRanksFrom1&#41;)
                       + 10 * min&#40;min&#40;bkFilesFromA, bkRanksFrom8&#41;, min&#40;bkFilesFromH, bkRanksFrom1&#41;);
            else
                score -= 20 * min&#40;max&#40;bkFilesFromA, bkRanksFrom1&#41;, max&#40;bkFilesFromH, bkRanksFrom8&#41;)
                       + 10 * min&#40;min&#40;bkFilesFromA, bkRanksFrom1&#41;, min&#40;bkFilesFromH, bkRanksFrom8&#41;);
        &#125;
        else
        &#123;
			int wkRank = &#40;position_fixed.white_king >> 3&#41;;
			int wkFile = &#40;position_fixed.white_king & 7&#41;;
			int wkRanksFrom1 = abs&#40;RANK_1 - wkRank&#41;;
			int wkRanksFrom8 = abs&#40;RANK_8 - wkRank&#41;;
			int wkFilesFromA = abs&#40;FILE_A - wkFile&#41;;
			int wkFilesFromH = abs&#40;FILE_H - wkFile&#41;;

            if &#40;position_fixed.bb&#91;eBlackBright&#93;)
                score += 20 * min&#40;max&#40;wkFilesFromA, wkRanksFrom8&#41;, max&#40;wkFilesFromH, wkRanksFrom1&#41;)
                       + 10 * min&#40;min&#40;wkFilesFromA, wkRanksFrom8&#41;, min&#40;wkFilesFromH, wkRanksFrom1&#41;);
            else
                score += 20 * min&#40;max&#40;wkFilesFromA, wkRanksFrom1&#41;, max&#40;wkFilesFromH, wkRanksFrom8&#41;)
                       + 10 * min&#40;min&#40;wkFilesFromA, wkRanksFrom1&#41;, min&#40;wkFilesFromH, wkRanksFrom8&#41;);
        &#125;
    &#125;
Now its much easier to see what's going on.

The min/max stuff is being used to calculate some approximate distances from certain corners of the board. I have no idea why this isn't just a pre-computed table, but whatever.

Note that min, max and abs can all be implemented in a branchless fashion on most platforms. I think Microsoft compilers always do this for abs(), but I'm not sure about min/max. Anyways, if you use your own macro you make it a lot harder for the compiler, which now has to try and do common-subexpression elimination on your stuff and turn it back into something sensible.

As we've seen here, nesting 2 or 3 levels of these macros quickly gets out of hand. Rather than assume your compiler can work miracles with recklessly-expanded macro code, you might prefer to use a non-macro version. Maybe something like this:

Code: Select all

// These could be optimized further to be branchless &#40;though good compilers will do it themselves anyhow&#41;
template<class T> __forceinline T min&#40;const T& a, const T& b&#41; &#123; return a <= b? a &#58; b; &#125;
template<class T> __forceinline T max&#40;const T& a, const T& b&#41; &#123; return a >= b? a &#58; b; &#125;
template<class T> __forceinline T abs&#40;const T& a&#41;             &#123; return a >= 0? a &#58; -a; &#125;

Daniel Shawul
Posts: 3577
Joined: Tue Mar 14, 2006 10:34 am
Location: Ethiopia
Contact:

Re: a cautionary tale about simple-looking macros

Post by Daniel Shawul » Sun Jul 03, 2011 7:53 pm

I recently tried to replace max,min, and abs with branchless inline functions. What prompted me to do that was the first time I profiled scorpio line by line with intel amplifier , the hot spots in eval in decreasing order were magics, popcnt, distance (and anywhere I have max,min,abs), score (mid/end game). I really did not expect distance to burn as much cycles for instance as popcnt. There was really nothing I can do about the first two, but I managed to improve very little by writing the manahattan distance calculator to use already calculated file and ranks. Branchless max,min, and abs did not bring anything though probably because msvc uses a branchless solution anyway.

Hot spots elsewhere were get_move (I pick the best move from scored move list), capture move generator etc.. I do not know if pre-sorting the list say using insertion sort would be better in some cases (at least on ALL nodes where all moves have to be searched), the capture generator was much faster with bitboards compared to my piece list engine.

I can see why top engines do spend time optimizing more or less these critical sections of an engine. But it was good to see for my self indeed this parts are time critical.

mcostalba
Posts: 2684
Joined: Sat Jun 14, 2008 7:17 pm

Re: a cautionary tale about simple-looking macros

Post by mcostalba » Sun Jul 03, 2011 8:46 pm

wgarvin wrote: That's still a little unwieldly, so I pulled out the abs() expressions to produce this version:
We could do some further step, here is rewritten in SF style.

Code: Select all

if (&#40;tower_dynamics->flag & 128&#41;)
&#123;
    if &#40;score > 0&#41;
    &#123;
        Square ksq = position_fixed.black_king;

        if &#40;position_fixed.bb&#91;eWhiteBright&#93;)
            score -=  20 * min&#40;square_distance&#40;ksq, SQ_A8&#41;, square_distance&#40;ksq, SQ_H1&#41;)

                    + 10 * min&#40;min&#40;file_distance&#40;ksq, FILE_A&#41;, rank_distance&#40;ksq, RANK_8&#41;),
                               min&#40;file_distance&#40;ksq, FILE_H&#41;, rank_distance&#40;ksq, RANK_1&#41;);
        else
            score -=  20 * min&#40;square_distance&#40;ksq, SQ_A1&#41;, square_distance&#40;ksq, SQ_H8&#41;)

                    + 10 * min&#40;min&#40;file_distance&#40;ksq, FILE_A&#41;, rank_distance&#40;ksq, RANK_1&#41;),
                               min&#40;file_distance&#40;ksq, FILE_H&#41;, rank_distance&#40;ksq, RANK_8&#41;));
    &#125;
    else
    &#123;
        Square ksq = position_fixed.white_king;

        if &#40;position_fixed.bb&#91;eBlackBright&#93;)
            score +=  20 * min&#40;square_distance&#40;ksq, SQ_A8&#41;, square_distance&#40;ksq, SQ_H1&#41;)

                    + 10 * min&#40;min&#40;file_distance&#40;ksq, FILE_A&#41;, rank_distance&#40;ksq, RANK_8&#41;),
                               min&#40;file_distance&#40;ksq, FILE_H&#41;, rank_distance&#40;ksq, RANK_1&#41;));
        else
            score +=  20 * min&#40;square_distance&#40;ksq, SQ_A1&#41;, square_distance&#40;ksq, SQ_H8&#41;)

                    + 10 * min&#40;min&#40;file_distance&#40;ksq, FILE_A&#41;, rank_distance&#40;ksq, RANK_1&#41;),
                               min&#40;file_distance&#40;ksq, FILE_H&#41;, rank_distance&#40;ksq, RANK_8&#41;));
    &#125;
&#125;
It seems to me that it is some code to penalize king when it is near to some board edge and penalize even more if it is near to corners of the same color of the enemy bishop.

wgarvin
Posts: 838
Joined: Thu Jul 05, 2007 3:03 pm
Location: British Columbia, Canada

Re: a cautionary tale about simple-looking macros

Post by wgarvin » Sun Jul 03, 2011 9:20 pm

I guess I should emphasize that there's nothing wrong with min/max macros if you are careful with the arguments. But they expand both arguments twice, and three of the four expanded arguments are executed. If you nest them like that Ippolit code did, or if you call functions with side effects inside, then expect some ugly surprises. ;) Back in the 80's, macros Of this sort were faster than a function. But that hasn't mattered for at least 10 years now.

Inline functions will not have those drawbacks, and with a good compiler they will be optimized at least as well as the macro versions.

User avatar
michiguel
Posts: 6386
Joined: Thu Mar 09, 2006 7:30 pm
Location: Chicago, Illinois, USA
Contact:

Re: a cautionary tale about simple-looking macros

Post by michiguel » Sun Jul 03, 2011 10:05 pm

mcostalba wrote:
wgarvin wrote: That's still a little unwieldly, so I pulled out the abs() expressions to produce this version:
We could do some further step, here is rewritten in SF style.

Code: Select all

if (&#40;tower_dynamics->flag & 128&#41;)
&#123;
    if &#40;score > 0&#41;
    &#123;
        Square ksq = position_fixed.black_king;

        if &#40;position_fixed.bb&#91;eWhiteBright&#93;)
            score -=  20 * min&#40;square_distance&#40;ksq, SQ_A8&#41;, square_distance&#40;ksq, SQ_H1&#41;)

                    + 10 * min&#40;min&#40;file_distance&#40;ksq, FILE_A&#41;, rank_distance&#40;ksq, RANK_8&#41;),
                               min&#40;file_distance&#40;ksq, FILE_H&#41;, rank_distance&#40;ksq, RANK_1&#41;);
        else
            score -=  20 * min&#40;square_distance&#40;ksq, SQ_A1&#41;, square_distance&#40;ksq, SQ_H8&#41;)

                    + 10 * min&#40;min&#40;file_distance&#40;ksq, FILE_A&#41;, rank_distance&#40;ksq, RANK_1&#41;),
                               min&#40;file_distance&#40;ksq, FILE_H&#41;, rank_distance&#40;ksq, RANK_8&#41;));
    &#125;
    else
    &#123;
        Square ksq = position_fixed.white_king;

        if &#40;position_fixed.bb&#91;eBlackBright&#93;)
            score +=  20 * min&#40;square_distance&#40;ksq, SQ_A8&#41;, square_distance&#40;ksq, SQ_H1&#41;)

                    + 10 * min&#40;min&#40;file_distance&#40;ksq, FILE_A&#41;, rank_distance&#40;ksq, RANK_8&#41;),
                               min&#40;file_distance&#40;ksq, FILE_H&#41;, rank_distance&#40;ksq, RANK_1&#41;));
        else
            score +=  20 * min&#40;square_distance&#40;ksq, SQ_A1&#41;, square_distance&#40;ksq, SQ_H8&#41;)

                    + 10 * min&#40;min&#40;file_distance&#40;ksq, FILE_A&#41;, rank_distance&#40;ksq, RANK_1&#41;),
                               min&#40;file_distance&#40;ksq, FILE_H&#41;, rank_distance&#40;ksq, RANK_8&#41;));
    &#125;
&#125;
It seems to me that it is some code to penalize king when it is near to some board edge and penalize even more if it is near to corners of the same color of the enemy bishop.
Yes, there was a thread about this long time ago, in which Zach Wegner explained it. One example of Macro's horror.

Miguel

rbarreira
Posts: 900
Joined: Tue Apr 27, 2010 1:48 pm

Re: a cautionary tale about simple-looking macros

Post by rbarreira » Sun Jul 03, 2011 10:07 pm

I believe macros should never be supplied by an API unless there's a very good reason for it, particularly when they evaluate arguments more than once...

Making a macro to be used by other people (possibly not very knowledgeable people) is simply asking for trouble, especially when people might not even notice that they're macros.

AlvaroBegue
Posts: 913
Joined: Tue Mar 09, 2010 2:46 pm
Location: New York
Full name: Álvaro Begué (RuyDos)

Re: a cautionary tale about simple-looking macros

Post by AlvaroBegue » Tue Jul 05, 2011 3:13 pm

If you give the compiler the opportunity to inline the function calls, is there any reason to use macros for these things? I haven't done that in years...

bob
Posts: 20358
Joined: Mon Feb 27, 2006 6:30 pm
Location: Birmingham, AL

Re: a cautionary tale about simple-looking macros

Post by bob » Tue Jul 05, 2011 8:53 pm

AlvaroBegue wrote:If you give the compiler the opportunity to inline the function calls, is there any reason to use macros for these things? I haven't done that in years...
One has to still be clever at times. Functions like "Lock() and "Unlock()" can be problematic if you are not careful, as the optimizer can do unexpected things there as well.

well-written macros work just fine, IMHO. Of course, any sort of syntactical construction can be abused and byte you in the azz if you go overboard. :)

Post Reply