tags:

views:

517

answers:

8

I ran across some very interesting code that makes me wonder about what bool is. I've always considered it to be a primitive type, like int or char or long. But today, I saw something that looked like this:

void boolPtrTest()
{
    bool thisBool = true;

    boolPtrHere(thisBool);

    printf("thisBool is %s\n", thisBool ? "true" : "false");
}

void boolPtrHere(bool& theBool)
{
    theBool = false; // uhh, dereferencing anyone?
}

And this code runs - no errors - and prints "thisBool is false"!

To further make this odd, I ran the following code:

bool myBool = new bool();

...and the code ran fine!

Before you go and downvote me for asking a "noobish" question

Here's my question: what is bool? Is it defined on an implementation-by-implementation basis? From the evidence shown above, I would say that it's a class. From a practical standpoint (disregarding the above), it would also seem proper to define a bool as a typedef to an int / char or have it #define'd. But how does one know what it is, (which would affect how you would treat it)?

EDIT: I thought I'd add that I'm working in VS 2008.

+11  A: 
void boolPtrHere(bool& theBool)
{
    theBool = false; // uhh, dereferencing anyone?
}

There is nothing wrong with this code. The bool is taken by reference. No dereferencing is required.

bool myBool = new bool();

new returns an address, which is converted to true, since it never returns a nonzero value. This is a common conversion, especially in C code:

int* my_int = malloc(10 * sizeof(int));
if (!my_int) // my_int is converted to bool
    memory_error();
rlbond
Well, never except in cases of memory exhaustion where `nothrow` semantics are specified. But yeah, I suppose that's pedantry. :)
Jonathan Grynspan
That expression, as written, will never result in `myBool` being false. Other expressions obviously can, but there's not much to be gained from enumerating them.
Dennis Zickefoose
@Dennis: it might in a dysfunctional environment where exceptions are disabled and all `new` expressions have an implicit `nothrow`. I've worked on more than one codebase where this is the case.
Mike Seymour
@Jonathan Grynspan: And where would we be without pedantry? +1
TokenMacGuy
@Mike: But then it's non-standard. Anyone can try to throw in corner cases, but then you're no longer working in standard C++. In standard C++ `new bool` **never ever throws**.
GMan
@GMan: non-standard indeed, but some of us still have to deal with it. I just felt like venting; apologies if I offended any C++ purists.
Mike Seymour
@Mike: That's okay. I just re-read my comment and realized I wrote `new bool` never throws...I mean never returns 0! :s
GMan
+19  A: 

I just don't see the "weirdness" you describe.

You declare a bool, initialized to true. By calling a function and passing it by reference, you change its value to false.

Then you print out the value, and it works. What is the problem? More precisely, what is the evidence that something strange is happening?

Since you want to know the details, bool is probably either a byte(char) or an int. When you assign it true/false, it gets the values 0 or 1. (use sizeof and printf("%d") to examine it).

I suspect the real issue is that you don't understand the pass-by-reference of boolPtrHere. You are not passing a pointer to the bool. You are passing the actual value by memory reference. (think of it as a pointer that you do not need to de-reference).

abelenky
But! But! But! The function is called bool PTR Here and they just pass it a bool!
Noah Roberts
Your function name is wrong, that's all. It doesn't prove that bool is some sort of magic, in fact it is a primitive type.
Ben Voigt
+9  A: 

bool is a fundamental type; true and false are the only two values that an object of type bool that has been initialized can have.

Your function boolPtrHere() does not take a pointer to a bool (which would be a bool*); it takes a reference to a bool. It works like any other reference in C++.

As for your last example:

bool myBool = new bool();

In C++, a pointer is implicitly convertible to bool. The new expression returns a pointer to a dynamically allocated bool object. This pointer is then converted to a bool and is stored in myBool. If the pointer is null, then myBool will be false; otherwise it will be true (since new never returns null, myBool will always be true in this case).

James McNellis
+4  A: 

Bool is a well-defined primitive integral type, just like int, char, etc. It also has mathematical conversions to other integral types, which can sometimes be confusing for people, but I don't think that is the source of your current confusion.

I'm not sure what you find remarkable about the first code segment you included. Bools can be references, just like anything else. It seems maybe you're confused about the difference between a pointer and a reference there.

As for the second code snippet, that is a little tricky. that is actually a memory leak, and if we write it a different way, it should become more clear what it is doing:

 bool myBool = (new bool) != 0 ? true : false;

from that, you can see what this is doing is allocating a bool from the heap, then comparing the result to NULL/0, and using the result of that comparison for assignment to the boolean. Note that the value originally allocated from the heap is leaked. I'm a little surprised this doesn't generate a compiler error for you, I would suspect on some compilers it would.

SoapBox
+1  A: 

References don't need to be dereferenced. Pointers do.

StackedCrooked
A: 

Think of it this way:

typedef enum { false=0, true=1 } bool;
bluesmoon
A: 

I've always considered it to be a primitive type, like int or char or long.

It seems that you are looking at C++ from Java perspective. In Java, primitive types are always passed by value and others are always references.

C++ is different. Any type can be a reference if declared that way. You can also declare int &x or int *x, so there is nothing weird about bool.

zvonimir
A: 

One very small surprise about bool is sizeof(bool) >= 1. A bool requires a full byte of storage. This is so that they can have a unique address and be pointed to, as in the boolPtrHere function.

TokenMacGuy
`sizeof(bool)` is at least 1, for the reason you stated, but can be larger.
Dennis Zickefoose
It's size is implementation-defined, and not necessarily 1.
GMan