matevzb wrote On 08/13/07 13:35,:
> I've ran into some fishy code that, at first glance, is buggy, but it
> seems to work correctly
> and none of the compilers I've tried (five so far, on various systems)
> gives any warnings.
> The code:
> ============================
> #include <stdio.h>
>
> void
> fcn (char *str)
> {
> if (str == '\0')
> {
> printf ("str!\n");
> }
> }
>
> int
> main (void)
> {
> fcn ('\0');
> return 0;
> }
> ============================
> My understanding so far: '\0' is passed to fcn(), it equals integer 0,
> which in turn "equals"
> a NULL pointer in terms of zero-ness. The 0 in fcn() is then compared
> to '\0' which is also a 0.
> No warnings, no errors, code works (or so it seems).
> But - if I pass e.g. '\1' to fcn() than all the compilers complain
> with similar warnings,
> i.e. making a pointer from integer without a cast.
>
> My question is, why don't the compilers complain when '\0' is passed?
> Shouldn't they give
> the same warning, as it's also an integer (albeit 0 in value)?
A literal constant zero[*] used in a pointer context
*is* a null pointer constant. In the code above, '\0'
is just a decorative way to write a literal constant zero.
The compiler sees that it's being used where a pointer is
expected, so the compiler recognizes the zero as a null
pointer constant instead of as an integer. Indeed, you
will find that on many systems the NULL macro is defined
as an unadorned zero.
[*] Any zero-valued constant integer expression will
do; try `fcn (42 / 100)', for example. Also, the
expression is still a null pointer constant if it
is cast to `void*'.
This special treatment applies only to
- Zero-valued expressions: If the expression's value
is non-zero, the expression cannot be a null pointer
constant. That's why the compiler complained when
you tried to use '\1' as an argument to fcn().
- Integer-valued expressions: If the expression's type
is `double' or `float' or `struct fubar', it is not
a null pointer constant. fcn(0.0) won't work.
- Constant expressions: If the expression is not a
compile-time constant, it is not a null pointer
constant. fcn(x - x) won't work; you can deduce
that the argument will always be zero, but from
the compiler's point of view it's just a remarkable
coincidence.
The FAQ has a section devoted to null pointers; you
might find it helpful.
--