Whether false
is allowed to be implicitly converted to pointer is different between clang++ and g++:
g++-4.8: always a warning with or without -std=c++11
clang++ (trunk): a warning if without -std=c++11, and an error if with -std=c++11
So anyone knows why g++ and clang++ behaves differently, and who is correct? What paragraphs in C++ standard (both C++03 and C++11) talks about the situation.
Thanks.
[hidden ~]$ cat b.cpp
const char* f() { return false; }
[hidden ~]$ g++ -c b.cpp
b.cpp: In function ‘const char* f()’:
b.cpp:1:26: warning: converting ‘false’ to pointer type ‘const char*’ [-Wconversion-null]
const char* f() { return false; }
^
[hidden ~]$ g++ -std=c++11 -c b.cpp
b.cpp: In function ‘const char* f()’:
b.cpp:1:26: warning: converting ‘false’ to pointer type ‘const char*’ [-Wconversion-null]
const char* f() { return false; }
^
[hidden ~]$ clang++ -c b.cpp
b.cpp:1:26: warning: initialization of pointer of type 'const char *' to null from a constant boolean expression [-Wbool-conversion]
const char* f() { return false; }
^~~~~
1 warning generated.
[hidden ~]$ clang++ -std=c++11 -c b.cpp
b.cpp:1:26: error: cannot initialize return object of type 'const char *' with an rvalue of type 'bool'
const char* f() { return false; }
^~~~~
1 error generated.
- In the context of a direct-initialization, a bool object may be initialized from a prvalue of type std::nullptr_t, including nullptr. The resulting value is false.
Comparing any variable with NULL will always evaluate to FALSE, regardless if it's value, unless IS NULL or IS NOT NULL is used. Violating this rule will affect the functionality of the code. The severity is critical which means that the code will not function correctly.
A null pointer has a reserved value that is called a null pointer constant for indicating that the pointer does not point to any valid object or function. You can use null pointers in the following cases: Initialize pointers. Represent conditions such as the end of a list of unknown length.
An implicit conversion sequence is the sequence of conversions required to convert an argument in a function call to the type of the corresponding parameter in a function declaration. The compiler tries to determine an implicit conversion sequence for each argument.
I'd say clang with C++11 is right:
3.9.1 Fundamental types [basic.fundamental]
6 Values of type bool are either
true
orfalse
. [ Note: There are no signed, unsigned, short, or long bool types or values. — end note ] Values of type bool participate in integral promotions (4.5).
bool
does not have value zero, so can not be converted to null pointer:
4.10 Pointer conversions [conv.ptr]
1 A null pointer constant is an integral constant expression (5.19) prvalue of integer type that evaluates to zero or a prvalue of type std::nullptr_t. A null pointer constant can be converted to a pointer type;
One might suggest conversion sequence consisting of integral promotion (bool
to int
) and null pointer conversion, but it would not be valid:
4 Standard conversions [conv]
1 Standard conversions are implicit conversions with built-in meaning. Clause 4 enumerates the full set of such conversions. A standard conversion sequence is a sequence of standard conversions in the following order:
- Zero or one conversion from the following set: lvalue-to-rvalue conversion, array-to-pointer conversion, and function-to-pointer conversion.
- Zero or one conversion from the following set: integral promotions, floating point promotion, integral conversions, floating point conversions, floating-integral conversions, pointer conversions, pointer to member conversions, and boolean conversions.
- Zero or one qualification conversion.
[ Note: A standard conversion sequence can be empty, i.e., it can consist of no conversions. — end note ] A standard conversion sequence will be applied to an expression if necessary to convert it to a required destination type.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With