Latest gcc 13.x (trunk) gives a compiler error (gcc -std=c23) for this code:
int* p = false;
error: incompatible types when initializing type '
int *' using type '_Bool'
How can this be correct?
C23 6.2.5 §8-9 (Types - the definition of integer types):
The type
booland the unsigned integer types that correspond to the standard signed integer types are the standard unsigned integer types.The standard signed integer types and standard unsigned integer types are collectively called the standard integer types;
C23 6.6 §8 (Constant expressions - the definition of an integer constant expression):
An integer constant expression shall have integer type...
C23 6.3.2.3 (Pointers - the definition of null pointer constant)
An integer constant expression with the value 0, such an expression cast to type
void *, or the predefined constantnullptris called a null pointer constant
C23 6.5.16.1 (Simple assignment):
Constraints
/--/
- the left operand is an atomic, qualified, or unqualified pointer, and the right operand is a null pointer constant
Conclusion:
int* p = false;is a valid form of assignment,- because
falseis a null pointer constant, - since it is an integer constant expression,
- since it has type
bool, which is one of the standard integer types.
Did I misunderstand anything in the standard or is this a gcc bug? clang gives a warning but still produces an executable. I don't really see how any of the above has changed in C23 either.
Including stdbool.h and compiling under gcc -std=c17 -pedantic-errors makes it compile cleanly as expected.
In addition to the paragraphs quoted in the question, there is paragraph 6.4.4.5/3:
and 6.6/7:
That makes
falsea named constant, which is relevant because a fuller quotation of 6.6/8 is(emphasis added).
Regardless, then, of GCC implementation details surrounding the constant
false, when taken as an expression,falsemeets C23's criteria for an integer constant expression. Its value is specified to be 0. It is therefore a valid null pointer constant.GCC's behavior here is contrary to the language spec.
None of the points you were referring to changed in C23, but what did change is the type of
falseandtrue. In C17, these had typeint. In C23, they have typebool(a.k.a._Bool). As you observe, however,boolis an integer type, so GCC not allowing that as the type of a null pointer constant is non-conforming.I note that GCC 8.5 does not accept
_Boolas a valid type for a null pointer constant, either. Given this source:, it fails with the same error you observed:
Thus, your observation appears to be a manifestation of a larger, relatively longstanding issue that is not specific to C23.
This issue is mentioned in the GCC bug tracker in comments on a related issue: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=112556.