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;
b开发者_JS百科oolPtrHere(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.
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).
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();
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).
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.
References don't need to be dereferenced. Pointers do.
Think of it this way:
typedef enum { false=0, true=1 } bool;
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.
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.
精彩评论