Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!samsung!rex!ames!haven!udel!princeton!notecnirp!nfs From: nfs@notecnirp.Princeton.EDU (Norbert Schlenker) Newsgroups: comp.lang.c Subject: Re: ANSI/Non-ANSI Function Declaration Macros Message-ID: <22472@princeton.Princeton.EDU> Date: 18 Dec 89 05:04:55 GMT References: <4603@itivax.iti.org> <244@isgtec.UUCP> <22402@princeton.Princeton.EDU> <248@isgtec.UUCP> Sender: news@princeton.Princeton.EDU Reply-To: nfs@notecnirp.UUCP (Norbert Schlenker) Organization: Dept. of Computer Science, Princeton University Lines: 95 In article <248@isgtec.UUCP> peter@isgtec.UUCP (Peter Curran) writes: (in response to my demurral at his suggestion) >In article <22402@princeton.Princeton.EDU> nfs@notecnirp.UUCP (Norbert Schlenker) >writes (in response to my suggesting for combining prototypes with the >obsolescent forms of functions, to port between ANSI and non-ANSI compilers): >Not as far as I can see, unless I have badly mis-read the ANSI standard >(which is certainly possible :-)) > >First, I assume that, in ANSI, the following are exactly equivalent: > > void func (char c, short n) > {...} >and > void func (c, n) > char c; > short n; > {...} Not so; see below. >They are just different syntax for the same thing. I would like to be >corrected if I have misunderstood this. > >My prototype here would be > > void func P((char c, short n)); > >Assuming I am right, then the use of the obsolescent form of function >header is irrelevant (except that it allows the code to be compiled >with K&R compilers.) ANSI compilers will see the prototype, and will >not widen the parameters; K&R compilers will not see the prototype >(which they can't handle), and will widen the parameters. Assuming all >the code is compiled with the same compiler (i.e. both the function >and all calls to it), then widening will always be done, or it won't >be done. I don't have a copy of the standard handy here, so I can't quote chapter and verse. But in response to feeding the program: int func(char c, short s); int func(c, s) char c; short s; { return 0; } into two (claimed) ANSI compilers, I get: From gcc: test.c: In function func: test.c:6: argument `c' doesn't match function prototype test.c:6: a formal parameter type that promotes to `int' test.c:6: can match only `int' in the prototype test.c:6: argument `s' doesn't match function prototype test.c:6: a formal parameter type that promotes to `int' test.c:6: can match only `int' in the prototype From lcc (a locally developed ANSI compiler): test.c:6: conflicting argument declarations for function `func' The messages from gcc are rather more clear than those from lcc. In both cases, though, it is an error to specify something shorter than 'int' in a prototype and then define it correspondingly in the actual function, if that definition is of the old K&R type. I believe, and the compilers believe, that the prototype which matches the actual definition: int func(c, s) char c; short s; {} must be: int func(int c, int s); Note also that changing the actual function header from: int func(c, s) char c; short s; to: int func(char c, short s) makes the ANSI compilers happy (and of course annoys the K&R compilers). Perhaps the language lawyers with quick access to X3J11 can verify this with a section number. Norbert