tags:

views:

500

answers:

5

When should BOOL and bool be used in C++ and why?

I think using bool is cleaner and more portable because it's a built-in type. But BOOL is unavoidable when you interactive with legacy code/C code, or doing inter-op from .NET with C code/Windows API.

So my policy is: Use bool inside C++. Use BOOL when talk to outer world, e.g., export function in windows DLL.

Is there a definitive explanation of when to use one over the other?

+3  A: 

Apparently, there's no good reason to use BOOL:

http://blogs.msdn.com/oldnewthing/archive/2008/03/25/8334558.aspx
http://blogs.msdn.com/oldnewthing/archive/2004/12/22/329884.aspx

Bastien Léonard
Of course there is a good reason. The second article says that Win32 uses BOOL to remain C compatible. You will need to use BOOL if you are working with legacy code.
A. Levy
I don't see why I would need to use BOOL, since C99 supports bool, and all C89 compilers I've used support it too. Also, the question is tagged as C++, not C.
Bastien Léonard
I always upvote The Old New Thing links... soooo +1
Aardvark
It'd be a lot simpler if I could just change the Win32 API and MFC to use modern C++ constructs, but since I can't I have to interface with them. Where I work, we've got three distinct array-type classes.
David Thornley
+3  A: 

Matthew Wilson discusses BOOL, bool, and similar in section 13.4.2 of Imperfect C++. Mixing the two can be problematic, since they generally have different sizes (and so pointers and references aren't interchangeable), and since bool isn't guaranteed to have any particular size. Trying to use typedefs or conditional compilating to smooth over the differences between BOOL and bool or trying to allow for a single Boolean type to work in both C and C++ is even worse:

#if defined(__cplusplus) || \
    defined(bool) /* for C compilation with C99 bool (macro) */
 typedef bool   bool_t;
#else
 typedef BOOL   bool_t;
#endif /* __cplusplus */

This approach means that a function's return type can differ depending on which language calls it; Wilson explains that he's seen more than one bug in his own code and others' that results from this. He concludes:

The solution to this imperfection is, as it so often is, abstinence. I never use bool for anything that can possibly be accessed across multiple link units—dynamic/static libraries, supplied object files—which basically means not in functions or classes that appear outside of header files. The practical answer, such as it is, is to use a pseudo-Boolean type, which is the size of int.

In short, he would agree with your approach.

Josh Kelley
I completely fail to understand why a 32-bit integer would have problems with converting to bool. A conversion to bool is simple: zero converts to false, anything else converts to true. If Wilson was chopping off a byte of a 32-bit integer, which is the only way I see this could happen, then the solution is to write code without stupid tricks, and let the compiler handle the conversions. Similarly, there is no danger in converting from a third-party BOOL to a C++ bool, unless one is determined to screw it up.
David Thornley
You're right, I failed to follow his example closely enough and so left out some important information. (Wilson agrees that it was a stupid mistake but argues that code should be as idiot-proof as possible.) I updated my summary to explain better.
Josh Kelley
+1  A: 

Another situation where you should use BOOL: when implementing a callback function that takes or returns a BOOL.

For example, EnumWindows() takes a pointer to a callback function with the following signature:

BOOL CALLBACK EnumWindowsProc(      
    HWND hwnd,
    LPARAM lParam
);

If you use bool for this, you will have to typecast your function pointer.

bk1e
+3  A: 

If BOOL is some sort of integral type, and it always is, and BOOL is defined so that it works right, the standard conversions will automatically get it right. You can't quite use them interchangeably, but you can get close.

Use BOOL at the interface, where you have to talk to the Win32 API or whatever. Use bool everywhere else.

David Thornley
A: 

I think of "true"/"TRUE" and "false"/"FALSE" as syntactic sugar, a solution to a problem that never existed. I've always thought it easier to both use and read "1" and "0".

When you think about flags in registers being on or off, do you think in 1s and 0s or trues and falses? What happens if you want to store several flags in a single variable? 1s and 0s are universal.

I think the word "false" is too long for its own good. When I see a "0", it stands out in my mind like a red stop sign. Stop signs are red because the color red gets people's attention. Reading the word "false" is like seeing a green stop sign.

So, to hell with bool and BOOL. I default to int.

...but, really, getting boolean flags right is the least worry in a language with as many ways to make a mistake as C++.

Steel
That's like saying a combat knife is dangerous because it can poke out your eye. Son, you need to keep your knife sharp and handle it with respect. Because, yes, it will take out your eye if you're flailing it about.
knight666
A problem that never existed? Really? If you see a function that has return type `bool` it tells you that it can return true or false. If you see one that has return type `int` what does that tell you?
jalf