wing wrote:Bitfields are not portable in C, i.e. the language does not define what the MSB and LSB will be. Is there a problem with that?
I want to use bitfields (UNION-ed with an unsigned integer) to store a move, and do not intend to do any masking or shifting on the fields.
I only need 24 bits, but intend to inflate this to 32-bit, so a move will be aligned with a 32-bit integer, which might be faster on some compilers/systems.
But still wonder if there might be reason for not using bitfields? any thoughts?
- Code: Select all
union Move {
struct {
unsigned from : 8;
unsigned to : 8;
unsigned movingPiece : 8;
unsigned capturedPiece : 4;
unsigned promoteTo : 4;
};
unsigned int moveInt;
};
Hi Stef,
Big-endian/little-endian only matters if you intend to save binary information on one endian-type and intend to read it on an opposite-endian machine. For bitfields it is very similar except that the implementation might vary from one compiler to another. For a normal chess engine it does not matter that a bitfield starts with low bits or high bits. The compiler will keep perfect track of which bits it used within your move structure.
If you save the move structure bitfields to disk,
as long as you use the same compiler to read it back into memory, then you can be assured that it will always work consistently. But saving/reading moves in GCC format and saving/reading in Microsoft compiler format might be different.
FYI, according to K&R: all bitfields are 32-bit integers, and
no guarantees are made whether a bitfield can cross a word boundary. Because of the doubt of whether my code might work on one compiler but not another due to bitfields not aligning with words, that makes it a deal-breaker for me. I always mask and shift and it will work with all compilers. I have always suspected that all the major compilers can cross word boundaries, but I don't want to cause weird bugs in case there's a compiler out there that can't do it properly.
Best regards,
Ron