| int (*foo) ();
According to the standard (3.3.2.2)
If the expression that denotes the called function
has a type that does not include a prototype, the
integral promotions are performed on each argument
and arguments that have type float are promoted to
double. These are called the default argument
promotions.
So in the calls using foo that follow
int (*foo)();
char c = 'a';
float f = 3.0;
foo = whatever;
int result1 = (*foo)(c);
int result2 = (*foo)(f);
the results are that the arguments are promoted before being
passed to *foo. However, these prototypes
int www(float);
int xxx(char);
specify functions which take an unpromoted float or char
argument. You cannot call www or xxx through *foo, because
they both expect a type of argument that a call through *foo
can never pass. For example, on OpenVMS VAX the calls
(*foo)(257);
(*foo)(3.0);
will call whatever function foo points to with argument lists
ap: 1
ap+4: 257
and
ap: 2
ap+4: 1st longword of (double)3.0
ap+8: 2nd longword of (double)3.0
But at runtime xxx must see (given 'int xxx(char);')
ap: 1
ap+4: a valid 'char' -- 257 is not a valid 'char'
and www must see
ap: 1
ap+4: a float value (F_Float)
These calls likely aren't going to work (especially with
CC/G_FLOAT) on OpenVMS VAX, a very forgiving system as far as
mistaken assumptions about C go, and the results may be even
worse on other platforms.
According to the C standard, that truly is a pointer
mismatch, which is why the compiler diagnoses it as such.
Dan
|