The place in the standard that permits the above is the set of all the
syntax rules and constraints that it doesn't violate.
As for replacing "0" by "main", that doesn't violate any syntax rule
or contraint either, and in fact it seems to work. The behavior of
converting main (a function pointer, after it decays) to st* is
undefined, but I don't know of any constraint that the conversion
violates.
For example this program:
#include <stdio.h>
#define msizeof(st, m) (sizeof(( (st *)(main) )->m))
int main(void)
{
struct foo { int x; int y; };
printf("msizeof(struct foo, y) = %d\n", (int)msizeof(struct foo, y));
return 0;
}
prints "4" on my system, though with "-pedantic" it produces a warning:
c.c: In function `main':
c.c:8: warning: ISO C forbids conversion of function pointer to object pointer type
I believe this warning is incorrect.
Note that C99 6.3.2.3, which describes pointer conversions, says that
pointers to object or incomplete types may be converted back and forth,
as may pointers to (possibly different) function types. But that's
not a constraint.
C99 6.5.4, which describes the cast operator, has the following constraints,
none of which are violated here:
Unless the type name specifies a void type, the type name shall
specify qualified or unqualified scalar type and the operand shall
have scalar type.
Conversions that involve pointers, other than where permitted by
the constraints of 6.5.16.1, shall be specified by means of an
explicit cast.
Constraints and syntax rules, yes. There is no runtime behavior, so
it doesn't matter that the behavior is undefined.
--
Keith Thompson (The_Other_Keith) (e-mail address removed) <
http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"