This code is neither legal C nor legal C++.
N1570 §6.7.9/p11:
The initializer for a scalar shall be a single expression, optionally
enclosed in braces. The initial value of the object is that of the
expression (after conversion); the same type constraints and
conversions as for simple assignment apply, taking the type of the
scalar to be the unqualified version of its declared type.
§6.5.16.1/p1 provides that for simple assignment:
One of the following shall hold:
- the left operand has atomic, qualified, or unqualified arithmetic type, and the right has arithmetic type;
- the left operand has an atomic, qualified, or unqualified version of a structure or union type compatible with the type of the right;
- the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue
conversion) both operands are pointers to qualified or unqualified
versions of compatible types, and the type pointed to by the left has
all the qualifiers of the type pointed to by the right;
- the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue
conversion) one operand is a pointer to an object type, and the other
is a pointer to a qualified or unqualified version of
void
, and the
type pointed to by the left has all the qualifiers of the type pointed
to by the right;
- the left operand is an atomic, qualified, or unqualified pointer, and the right is a null pointer constant; or
- the left operand has type atomic, qualified, or unqualified
_Bool
, and the right is a pointer.
None of which matches a pointer on the left and 333
on the right. §6.5.16.1/p1 is a constraint, and conforming implementations are required to produce a diagnostic upon a constraint violation (§5.1.1.3/p1):
A conforming implementation shall produce at least one diagnostic
message (identified in an implementation-defined manner) if a
preprocessing translation unit or translation unit contains a
violation of any syntax rule or constraint, even if the behavior is
also explicitly specified as undefined or implementation-defined.
It happens that GCC decides to produce a warning instead of an error in C mode and continue to compile it, but it doesn't have to.