Thread overview
Converting C/C++ Code to D (#define extern)
Sep 26, 2006
exiquio
Sep 26, 2006
Serg Kovrov
Sep 26, 2006
Serg Kovrov
Sep 26, 2006
Hasan Aljudy
Sep 26, 2006
Serg Kovrov
Oct 03, 2006
Bill Baxter
Oct 03, 2006
Brad Roberts
Sep 26, 2006
Lutger
Sep 26, 2006
exiquio
September 26, 2006
Good day to all.

I am writing an chess engine based upon an established C++ engine as a interesting, yet practical excersise.

While translating a header file (I am not proficiant in C\C++) I ran into some things I find difficult findinf a way to do in D. Here are a few examples of what I am talking about (w/ no particular order):

CODE:

#define PawnListStart(pos,side) PieceListStart(pos,PawnOfColour(side))
#define KnightListStart(pos,side) PieceListStart(pos,KnightOfColour(side))
#define BishopListStart(pos,side) PieceListStart(pos,BishopOfColour(side))
#define RookListStart(pos,side) PieceListStart(pos,RookOfColour(side))
#define QueenListStart(pos,side) PieceListStart(pos,QueenOfColour(side))


#define MovePiece(pos,from,to) do {                 \
    PieceList(pos,to) = PieceList(pos,from);            \
    PrevPiece(pos,NextPiece(pos,to)) = to;      \
    NextPiece(pos,PrevPiece(pos,to)) = to;      \
  } while(0)


extern uint8 PawnRank[2][128];
extern attack_data_t AttackData_[256];
extern attack_data_t *AttackData;

END CODE

Forgive me for being ignorant and thanks in advance.
September 26, 2006
Hi exiquio, you wrote:
> #define PawnListStart(pos,side) PieceListStart(pos,PawnOfColour(side))
> #define KnightListStart(pos,side) PieceListStart(pos,KnightOfColour(side))
> #define BishopListStart(pos,side) PieceListStart(pos,BishopOfColour(side))
> #define RookListStart(pos,side) PieceListStart(pos,RookOfColour(side))
> #define QueenListStart(pos,side) PieceListStart(pos,QueenOfColour(side))
> 
> 
> #define MovePiece(pos,from,to) do {                 \
>     PieceList(pos,to) = PieceList(pos,from);            \
>     PrevPiece(pos,NextPiece(pos,to)) = to;      \
>     NextPiece(pos,PrevPiece(pos,to)) = to;      \
>   } while(0)

It is a good example of C-macros used when inline functions should be. Just define functions that do this stuff.

> result_type PawnListStart(pos_type pos, side_type side)
> {
>   return PieceListStart(pos, PawnOfColour(side));
> }
> ...
> void MovePiece(pos_type pos, from_type from, to_type to)
> {
>   do
>   {
>     PieceList(pos, to) = PieceList(pos,from);
>     PrevPiece(pos, NextPiece(pos, to)) = to;
>     NextPiece(pos, PrevPiece(pos, to)) = to;
>   }
>   while(0);
> }

Although later is somewhat suspicious - how loop meant to break?. Perhaps there is another macro called as function, that has a break statement. You could investigate what exactly it should do and rewrite it more clear.

-- 
serg.
September 26, 2006
Serg Kovrov wrote:
> do
> {
>   PieceList(pos, to) = PieceList(pos,from);
>   PrevPiece(pos, NextPiece(pos, to)) = to;
>   NextPiece(pos, PrevPiece(pos, to)) = to;
> }
> while(0);

> Although later is somewhat suspicious - how loop meant to break?. Perhaps there is another macro called as function, that has a break statement. You could investigate what exactly it should do and rewrite it more clear.

How stupid of me =)
> do {...} while(0);
will be called exactly one time, but it has no sense to me either...

-- 
serg.
September 26, 2006

Serg Kovrov wrote:
> Serg Kovrov wrote:
>> do
>> {
>>   PieceList(pos, to) = PieceList(pos,from);
>>   PrevPiece(pos, NextPiece(pos, to)) = to;
>>   NextPiece(pos, PrevPiece(pos, to)) = to;
>> }
>> while(0);
> 
>> Although later is somewhat suspicious - how loop meant to break?. Perhaps there is another macro called as function, that has a break statement. You could investigate what exactly it should do and rewrite it more clear.
> 
> How stupid of me =)
>> do {...} while(0);
> will be called exactly one time, but it has no sense to me either...
> 

I remember a long while ago I read something about writing macro functions like this. I forgot why you have to add do while(0) but it's a trick to make the macro a /little bit/ more robust ...
September 26, 2006
Hi Hasan Aljudy, you wrote:
> I remember a long while ago I read something about writing macro functions like this. I forgot why you have to add do while(0) but it's a trick to make the macro a /little bit/ more robust ...

You right, it is exactly robustness issue.

I think I understand now why - to use such multi-line macro with 'bracesless' (that is, one line) case of statements if/for/while. It is ugly-looking, but perhaps useful hack.

PS. good thing, we can learn here not just D stuff, but in fact other languages tricks as well =)

-- 
serg.
September 26, 2006
Nice, I'm sure the D code will be a lot cleaner. Have you found relevant links on digital mars? These I found useful:

http://www.digitalmars.com/d/htomodule.html
http://www.digitalmars.com/d/ctod.html
http://www.digitalmars.com/d/cpptod.html
http://www.digitalmars.com/d/pretod.html

If you're willing to share I would be interested in the end result.

exiquio wrote:
> Good day to all.
> 
> I am writing an chess engine based upon an established C++ engine as a interesting, yet practical excersise.
> 
> While translating a header file (I am not proficiant in C\C++) I ran into some things I find difficult findinf a way to do in D. Here are a few examples of what I am talking about (w/ no particular order):
> 
> CODE:
> 
> #define PawnListStart(pos,side) PieceListStart(pos,PawnOfColour(side))
> #define KnightListStart(pos,side) PieceListStart(pos,KnightOfColour(side))
> #define BishopListStart(pos,side) PieceListStart(pos,BishopOfColour(side))
> #define RookListStart(pos,side) PieceListStart(pos,RookOfColour(side))
> #define QueenListStart(pos,side) PieceListStart(pos,QueenOfColour(side))
> 
> 
> #define MovePiece(pos,from,to) do {                 \
>     PieceList(pos,to) = PieceList(pos,from);            \
>     PrevPiece(pos,NextPiece(pos,to)) = to;      \
>     NextPiece(pos,PrevPiece(pos,to)) = to;      \
>   } while(0)
> 
> 
> extern uint8 PawnRank[2][128];
> extern attack_data_t AttackData_[256];
> extern attack_data_t *AttackData;
> 
> END CODE
> 
> Forgive me for being ignorant and thanks in advance.
September 26, 2006
Thanks for the replying. I never really used newsgroups before, and this D ng is pretty impressive. I look forward to adding on to the community. I will share the final program (the UCI chess engine, and hopefully a UCI GUI) when it is working. I will probably post it to dsource.org. I believe in "free" software in the GNU since. I believe that D is an incledible language, so I think that even my amatuer code will be of some use.
October 03, 2006
Serg Kovrov wrote:
> Hi exiquio, you wrote:

>>
>> #define MovePiece(pos,from,to) do {                 \
>>     PieceList(pos,to) = PieceList(pos,from);            \
>>     PrevPiece(pos,NextPiece(pos,to)) = to;      \
>>     NextPiece(pos,PrevPiece(pos,to)) = to;      \
>>   } while(0)
> 

> Although later is somewhat suspicious - how loop meant to break?. Perhaps there is another macro called as function, that has a break statement. You could investigate what exactly it should do and rewrite it more clear.
> 

That's a C preprocessor trick so that a call to the macro can pretend to be a regular function call.  It allows you to introduce a local variable, or have an if-else or loop in the macro.  E.g.

#define MaybeDoIt(cond) if (cond) \
   { int ret; \
     ret = prepareToDoIt(); \
     doIt(); \
   }

If you write it like that you can't call it like "MaybeDoIt(false);". The ';' on the end is syntactically incorrect.  Many C/C++ compilers would barf on it.  So you wrap it in a do while which needs a ';' at the end:
#define MaybeDoIt(cond) do{\
   if (cond) \
   { int ret; \
     ret = prepareToDoIt(); \
     doIt(); \
   } \
   while(0)

In this case it's really not necessary, though.  No loops, if-elses, or local variables are introduced so it could just be:

 #define MovePiece(pos,from,to)                \
     PieceList(pos,to) = PieceList(pos,from);  \
     PrevPiece(pos,NextPiece(pos,to)) = to;    \
     NextPiece(pos,PrevPiece(pos,to)) = to

Then you would call it like "MovePiece(a,b,c);" from your code.

Either way this should just be made into a regular function.  (Which D will inline if it feels like it).

--bb
October 03, 2006
Bill Baxter wrote:
> Serg Kovrov wrote:
>> Hi exiquio, you wrote:
> 
>>>
>>> #define MovePiece(pos,from,to) do {                 \
>>>     PieceList(pos,to) = PieceList(pos,from);            \
>>>     PrevPiece(pos,NextPiece(pos,to)) = to;      \
>>>     NextPiece(pos,PrevPiece(pos,to)) = to;      \
>>>   } while(0)
>>
> 
>> Although later is somewhat suspicious - how loop meant to break?. Perhaps there is another macro called as function, that has a break statement. You could investigate what exactly it should do and rewrite it more clear.
>>
> 
> That's a C preprocessor trick so that a call to the macro can pretend to be a regular function call.  It allows you to introduce a local variable, or have an if-else or loop in the macro.  E.g.
> 
> #define MaybeDoIt(cond) if (cond) \
>    { int ret; \
>      ret = prepareToDoIt(); \
>      doIt(); \
>    }
> 
> If you write it like that you can't call it like "MaybeDoIt(false);". The ';' on the end is syntactically incorrect.  Many C/C++ compilers would barf on it.  So you wrap it in a do while which needs a ';' at the end:
> #define MaybeDoIt(cond) do{\
>    if (cond) \
>    { int ret; \
>      ret = prepareToDoIt(); \
>      doIt(); \
>    } \
>    while(0)
> 
> In this case it's really not necessary, though.  No loops, if-elses, or local variables are introduced so it could just be:
> 
>  #define MovePiece(pos,from,to)                \
>      PieceList(pos,to) = PieceList(pos,from);  \
>      PrevPiece(pos,NextPiece(pos,to)) = to;    \
>      NextPiece(pos,PrevPiece(pos,to)) = to
> 
> Then you would call it like "MovePiece(a,b,c);" from your code.
> 
> Either way this should just be made into a regular function.  (Which D will inline if it feels like it).
> 
> --bb

But you can't do:

if (cond)
    MovePiece(a, b, c);

and have it behave as you'd expect with your suggested definition but it would work as expected in the original form.  do/while loops form a valid block, and that's the key difference.

Later,
Brad