| Title: | DECC |
| Notice: | General DEC C discussions |
| Moderator: | TLE::D_SMITH N TE |
| Created: | Fri Nov 13 1992 |
| Last Modified: | Fri Jun 06 1997 |
| Last Successful Update: | Fri Jun 06 1997 |
| Number of topics: | 2212 |
| Total number of notes: | 11045 |
I'm sure this is a simple question. Why does the assignment of foo to
xxx fail in the attach but the assignment of yyy and zzz to foo
succeeds?
In other words when defining the routine pointer foo as a non
prototyped routine why does the compiler allow me to fill in that
pointer with addresses of certain types of routines but not others.
It appears that it only objects to routines that have one or more
"char" arguments in the actual routine. Other argument types seem
fine.
Attached is the program and the results of the compilation.
Thanks,
Dave
int (*foo) ();
int (*foo) ();
int xxx(char);
int yyy(int);
int zzz(char *);
main ()
{
foo = xxx;
foo = yyy;
foo = zzz;
}
$ cc b.c
foo = xxx;
^
%CC-W-PTRMISMATCH, In this statement, the referenced type of the
pointer value "
xxx" is "function (char) returning int", which is not compatible with
"function
() returning int".
at line number 8 in file USER1$:[GARROD]B.C;6
| T.R | Title | User | Personal Name | Date | Lines |
|---|---|---|---|---|---|
| 2182.1 | SPECXN::DERAMO | Dan D'Eramo | Fri May 09 1997 20:43 | 65 | |
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
| |||||