views:

678

answers:

10
+2  Q: 

BOOL definition

Whenever BOOL datatype is not readily predefined, I used to boolean with the following definition,

typedef unsigned char BOOL;

(Owing to memory usage).

I realized it may be better to use native bus width for performance reasons. For example, for a 32 bit processor it can be

typedef unsigned int BOOL;

Now, what will happen for the 64 bit processor, if I still want to define BOOL for the native bus width.

+12  A: 

I wouldn't worry about the native bus width so much as an efficient width (that was your goal, right)? On pretty much any machine, any decent c compiler will compile unsigned int to a reasonably efficient width, so you're good to go.

MarkusQ
One exception being standards compliant compilers for 8-bit microcontrollers. In that case an unsigned char is more efficient since 16-bits is the minimum int size.
Judge Maygarden
@monjardin Yes, and I suppose it might matter because he's talking about embedded. But does anyone really do much c on an 8-bit bus anymore? By that point I'd expect you'd be doing custom asm or something, and even so I'm not sure why.
MarkusQ
@MarkusQ, there are a lot more things still running 8-bit buses than you'd guess. The 8051 architecture looks like it will never die, for example, and the Z80 lives on too...
RBerteig
@RBerteig -- I have a warm spot in my heart for the Z80 (and a depressingly large fraction of my brain that says "call!" when it sees 0xCD, and "ret!" when it sees 0xC9, and "xor A with itself!" when it sees 0xAF, and...*sigh*). But my point was, who programs a Z80 in C? That seems almost criminal
MarkusQ
A: 

Well you could always define the typedef to long long or something, but I'm actually not sure this is something people do for some reason. (you could probably also do a conditional definition based on sizeof(int*) or something like that).

Assaf Lavie
+4  A: 

size_t

TofuBeer
I'm out of votes, so +1 tomorrow. size_t automatically expands to the widest available unsigned type.
Tim Post
+3  A: 

I would recommend to use preprocessor.

 #ifndef BOOL 
   #ifdef ILP32
     #define BOOL uint32_t
   #endif
   #ifdef LP64
     #define BOOL uint64_t
   #endif
 #endif
lakshmanaraj
+3  A: 

Why don't you use the bool type in stdbool.h?

Judge Maygarden
only if using C99
TofuBeer
Only if it is available.
Alphaneo
A: 

Using a char might be slower than using an integer.

Arafangion
+8  A: 

Never speculate on performances, measure. Measuring, will give the definitive answer on what is better - and remember this may change at each new compiler version, system upgrade ...

Also on day you might need an array of boolean, in which case using the processor word for a bool cannot be the best solution.

philippe
Just look at the number of assembly instructions that your code translates to, and also the clock cycles of each of them. In this case, measuring will become a bit difficult, I guess.
Alphaneo
Not sure I understood what your getting at. Let me clarify: I meant when wondering on performances at such a low level (ie not algorithm), comparing is better. Create a benchmark program with intensive use of bools and measure with char or bool and comapre to 64 bits bools.
philippe
You get into all sorts of fun things like memory alignment, how much data is fetched at a time, etc... where you need to know more than just the raw instruction set. But testing to verify is always a good thing.
TofuBeer
+2  A: 

At least x86 and ARM are capable of loading and storing a byte to and from a 32-bit register without any penalties, so there really is no performance impact for using char. I'm not entirely sure, but I'd bet that x86-64 has such instructions too. (Of course x86 and x86-64 can handle 8-bit values directly in registers too.).

So the only concern might be about memory layout. Of course the compiler aligns everything, so most of the time, char values in structs get padded, unless they are right next to each other, then you might actually save a few bytes of space and get a slightly better cache performance. If you have huge arrays of BOOLs and memory is a concern, you should bit pack them anyway.

In any case, it's a non-issue. Why don't you try running a program compiled both ways and see, if there's any significant impact on performance or memory usage. If you find that there is, you can buy yourself a beer and pretend it's from me.

TrayMan
If you pack(1), then obviously when loading, we the number of instruction to single out a bool is be more than just loading a native width words. Can you visualize this sitation?
Alphaneo
I'm not sure what you mean, but ARM has the ldrb/strb instructions for loading bytes. X86 can load a byte directly to the low 8-bits of registers (eq. mov al,[addr]) and there's movzx eax,[addr] to load a zero extended byte into eax.
TrayMan
@TrayMan -- Count cycles and bytes for non-aligned data to see what he means. There can be a significant penalty, and as murphy says if there can be there will be.
MarkusQ
How can a byte be unaligned? Even if the hardware has to read a full 32-bit word to get the byte, it still doesn't need to do an unaligned read.
TrayMan
+2  A: 

optimal for most platform

typedef enum { FALSE = 0, TRUE = 1, } BOOL;

vitaly.v.ch
Because then TRUE != !FALSE
Mikeage
???what do You mean? Iso c89 require !0 == 1.
vitaly.v.ch
A: 

int_fast8_t from stdint.h should be a good choice

dmityugov