Everything that can possibly be represented in a
machine
register with all bits clear shows up as an integral zero literal.
'\0' == 0 == nullptr == struct { } == union
{ }
Well, some things.
0.0f and other floating-point zero constants are represented
by all-zero words (of various sizes) and are not integral constants.
NULL does not "show up as an integral zero literal".
0==NULL is true only because 0 can be converted to NULL.
Getting really lawyerly, one can cook up any number of
bizarre "things that can possibly be represented" by an
all-zero word, for example (char[4]){0,0,0,0}, and have
no representation as an integral constant.
Only 3 of the 5 examples fit the description of possibly being
represented by an all-zero word.
struct{} and union{} are gnu extensions with size zero. Even
if you accept them as C, they have no machine representation
and cannot be cast to int.
The null pointer makes the list only thanks to the weasel-word
"possibly". Although 0 can be cast to the null pointer, the
result of casting a null pointer to int depends on its unspecified
machine representation. Zero, of course, is a good choice
because it's easy to test for, and is easy to omit from virtual
address spaces.
Doug