Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!yale!cmcl2!adm!smoke!gwyn From: gwyn@smoke.BRL.MIL (Doug Gwyn) Newsgroups: comp.std.c Subject: Re: May prototypes be required for lib functs Message-ID: <13759@smoke.BRL.MIL> Date: 6 Sep 90 20:57:53 GMT References: <478@hitachi.uucp> Organization: U.S. Army Ballistic Research Laboratory, APG, MD. Lines: 92 In article <478@hitachi.uucp> jon@hitachi.uucp (Jon Ryshpan) writes: >May an ANSI C compiler maker require that users of a compiler and its >libraries put prototypes for the lib functs in functions which call >these lib functs? I'm not quite sure what this is supposed to mean, but: 4.1.6 explicitly allows strictly conforming C programs to not include a standard header if they can properly declare a function without it. Furthermore, any function need not be declared using prototype ("new- style") syntax if its parameters have already-default-widened types (as I think all the standard library functions do). And any function need not be declared at all if it returns type int and its parameters have already-default-widened types. >For example it might be desirable for lib functs to pop their own >arguments (callee pops convention). This is clearly not possible >unless the callee knows the number and types of its arguments. I don't see the relevance of this. C functions are not in general polymorphic, and whether the caller or callee cleans up the stack does not matter (not for this discussion, anyway; it could matter to the implementor when longjmp, asynchronous signals or interrupts, and struct passing are taken into account). However, for variadic functions such as printf(), there must be a new-style declaration in scope for the function call; the declaration can be provided by a standard header or directly by the program. The reason for this is that otherwise the compiler would be unable to distinguish between invocation of a function with a fixed number of (default-widened) arguments and a function capable of taking a variable number of arguments, since the invocations for the two cases appear syntactically identical. Only the declaration shows which is intended, e.g. extern int printf(const char *, ...); /* variable arguments */ extern int pr_int(const char *, int); /* always 2 arguments */ Because the compiler may have to generate different linkage for these two cases (or at least, may prefer to avoid the additional variadic linkage overhead except when it is actually needed), the standard requires that prototypes be in scope when variadic functions are invoked, so that the compiler knows what linkage it needs to generate. >Is such a requirement is *permitted* under ANSI C, and is it a good >idea? Any implementation that requires inclusion of a standard header to declare a standard function, for example strcpy(), is not standard conforming. It is permitted for some of the standard functions to be implemented in the standard headers as macros, but there must still be actual function declarations in the headers, as well as function definitions present in the standard library, specifically to accommodate programs that directly declare the functions or otherwise deliberately take pains to avoid using the macro equivalents. When an implementation chooses to provide a macro implementation of a standard function, the associated standard header is required to BOTH declare the function AND THEN provide any macro equivalent that it wants programs to use by default. E.g. /* example conforming implementation's extract: */ extern char *strcpy(char *, const char *); #define strcpy(s1, s2) __intrinisic__strcpy(s1, s2) /* compiler treats above specially */ Any of the following program extracts are strictly conforming: #include ... strcpy(a, b); /* uses a macro if one was provided in , otherwise invokes a function */ or #include #undef strcpy /* in case it's defined in */ ... strcpy(a, b); /* accesses the library function */ or #include ... (strcpy)(a, b); /* accesses the library function */ or /* no included anywhere */ extern char *strcpy(); /* compatible old-style declaration */ ... strcpy(a, b); /* accesses the library function */