Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!uunet!taumet!steve From: steve@taumet.com (Stephen Clamage) Newsgroups: comp.lang.c Subject: Re: Protoize/Unprotoize (was: ANSI C to K&R syntax converter) Message-ID: <245@taumet.com> Date: 5 Jun 90 15:56:01 GMT References: <1990May31.214655.18960@csrd.uiuc.edu> <26699454.10047@paris.ics.uci.edu> <1645@mountn.dec.com> Reply-To: steve@taumet.UUCP (Stephen Clamage) Organization: Taumetric Corporation, San Diego Lines: 56 In article <1645@mountn.dec.com> minow@thundr.enet.dec.com (Martin Minow) writes: >I've had good results by writing prototypes using the following process: > [ details deleted ] > /* > * All functions are specified here: > */ > int sample _((int, char *, struct foo)); >The actual definition of a function uses the old -- but still valid -- syntax: > int sample(i, cp, foostruct) > int i; > char *cp; > struct foo foostruct; This will not work properly if any of the parameters are of type char, short, or float. If you are lucky, the ANSI compiler will complain about mismatched prototype and defintion if the prototypes are in scope when the definition occurs. Consider the prototype int foo(float f); and the definition int foo(f) float f; { ... } and the call to foo int x = foo(1.0); With an ANSI compiler, the compiler will see the prototype and know that foo expects to see a float parameter. It will pass a float version of 1.0 to foo(). At the definition point, assume the compiler doesn't see the prototype. It will see an old-style definition, and know that any caller will have actually passed a double, not a float, by the rules of default promotion. So it will expect to be passed a double, which is different in size and in format from floats on most machines. So the caller passes a different type than the called function expects. Sad to say, your solution is not portable. You can make it portable by conditionalizing the function definition: #if __STDC__ int sample(int i, char *cp, struct foo foostruct) #else int sample(i, cp, foostruct) int i; char *cp; struct foo foostruct; #endif { ... } Unfortunately, this is very ugly and error-prone. -- Steve Clamage, TauMetric Corp, steve@taumet.com