Is it acceptable to assign 'NULL' to a boolean datatype?
The compiler won't reject it since NULL is usually a preprocessor #define for 0 and 0 is convertable to a pointer representation of NULL and false.
No, You should use the technical term - "File Not Found"
edit:
Reference: http://thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx
The proper answer is No.
What I think you are trying to do is use NULL to mean "Uninitialized" or "Dunno, yet." This will usually work in a database, but won't always work in code as the definition of NULL varies from preprocessor to preprocessor and language to language.
Booleans are by definition two-state values. To try to use them as three-state values is an error. At best it's a dirty hack that will cause confusion to other developers in the future, at worst it's a breaking error, that will bite you in the behind as soon as anything in your build chain changes.
As long as false is still 0 and NULL is still defined to 0 yes, but this can change in the future. I'd say its bad practice because u mix concepts and lose clarity.
My opinion is that this will reduce the readability of your code, but sure if you want to. NULL is just 0 after all.
I'm not sure why you want to do that. If you're trying to initialize it, use 0. As MSN said, your compiler is not going to reject it. Perhaps you should explain why you want to set a bool to NULL in the first place?
From a theoretical point of view, yes. But it's a horrible thing to do.
NULL
is a null pointer constant that is assigned to a pointer to make it point to nothing.
...
ptr = NULL; // now it points to no object anymore
...
// or ptr == 0
if(ptr == NULL) {
...
}
Here are the references to the Standard if you are interested in any case. First, a null pointer constant is (4.10/1
)
A null pointer constant is an integral constant expression (5.19) rvalue of integer type that evaluates to zero.
Then, what happens if we convert a null pointer constant to bool
? It's explained in 4.12/1
:
An rvalue of arithmetic, enumeration, pointer, or pointer to member type can be converted to an rvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; a
(When it talks about rvalue
it essentially means a simple value as opposed to a variable of that type).
Now, what actually is that NULL
? Read 18.1/4
(note that in C, a null pointer constant is defined differently. Which might be the reason it explicitly refers to C++)
The macro NULL is an implementation-defined C++ null pointer constant in this International Standard
The important bit of that combination is the part "A zero value ... is converted to false
". An assignment of NULL
to a bool variable will try to convert NULL
to a boolean value. As the above passages say, such a conversion exist and can be done.
Another important thing about null pointers to understand is the different between a null pointer
and a null pointer constant
. As we just read, a null pointer constant is some integer value that's zero. However, a null pointer
and its value, a null pointer value
, are pointers and their type is of pointer type. The following has type int and is a null pointer constant
#define NULL ('n'-'n') // looks suspicious, but conforms
Because it is a integral constant expression (that is essentially an integer value that is known at compile time) with value zero. The following is a null pointer value
(void*)NULL
but it is not a null pointer constant. But anyway, also null pointer values are converted to bool as the above quote tells: "A .. null pointer value .. is converted to false
". So you are all fine.
From my copy of n2798:
18.1 Types
3 The macro NULL is an implementation-defined C++ null pointer constant in this International Standard (4.10)
and
4.12 Boolean conversions [conv.bool]
1 An rvalue of arithmetic, unscoped enumeration, pointer, or pointer to member type can be converted to an rvalue of type bool. A zero value, null pointer value, or null member pointer value is converted to false; any other value is converted to true. An rvalue of type std::nullptr_t can be converted to an rvalue of type bool; the resulting value is false.
So, yes, it seems likely that you can do that.
Since NULL is usually not 0 but (void*)0
, it does not work just like that in C++, since NULL is a pointer in this case. You would have to do an explicit cast: reinterpret_cast<bool>(NULL)
, and no this is not clean. You should use true
/1
and false
/0
NULL is not by definition 0. I don't know of any, but there could be some compilers that use a non-zero value for NULL, or perhaps even set some flag in a thunk behind its address. It would be just your luck that your code gets ported to one. It would be just my luck that I'd have to fix the resulting bugs.
So I say, "No, it is not acceptable."
In general it will work, since pointers are designed to be usable in a boolean context:
int *i = NULL;
if (i) // This is a pretty acceptable use of pointer conversions to bool
{
// never runs.
}
or
int *i = NULL;
...
bool b = i; // Maybe not so terrible, but you're better off just assigning to a pointer.
This is done on purpose (see dirkgently's answer for the standard reference) to allow this usage. If you are using this syntax:
bool i = NULL; // Don't do this
bool i2 = 0; // better
bool i3 = false; // Best
Then you are probably being misleading, but it's going to work in a portable, predictable fashion. Either NULL is defined to be 0, in which case, you will get a false value, or if NULL is truly a NULL pointer, then it will evaluate to false as well.
You can do that, but I don't see the point. Suppose you have:
void* p = NULL;
bool b = p;
Why not just write it as:
void* p = NULL;
bool b = (p != NULL);
It's clearer and any decent compiler will generate the same code.
Even if this is technically possible to do, I would avoid it. It seems that if you need a null value, you should model to a different data type than Boolean.
If you are going to use Boolean, properly design your module and code to use it as designed: with two potential values, not three. If you need three, use another data type, like int or string, and have each of the three values mean something (in string, null string would mean null).