[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference turris::decc

Title:DECC
Notice:General DEC C discussions
Moderator:TLE::D_SMITHNTE
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

2182.0. "Why PTRMISMATCH when "char" arguments?" by SMAUG::GARROD (IBM Interconnect Engineering) Fri May 09 1997 19:18

    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.RTitleUserPersonal
Name
DateLines
2182.1SPECXN::DERAMODan D'EramoFri May 09 1997 21:4365
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