Session transcript:
> type lookma.c int main() { printf("%s", "no stdio.h"); } > cl lookma.c Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.50727.762 for 80x86 Copyright (C) Microsoft Corporation. All rights reserved. lookma.c Microsoft (R) Incremental Linker Version 8.00.50727.762 Copyright (C) Microsoft Corporation. All rights reserved. /out:lookma.exe lookma.obj > lookma no stdio.h
In strict compliance mode (that means ‘in theory’), you invoke undefined behaviour (which is bad) when you call a function that takes a variable number of arguments without a prototype declaration of the function in scope. That means that the compiler is allowed to do anything it likes with a program that uses
printf()without the prototype from#include <stdio.h>or an equivalent declaration. ‘Anything it likes’ includes working correctly as one of the options; that seems to be the option chosen by your example.In practice, the code will work OK with most practical compilers even without the formal declaration of the
printf()function.As was pointed out by qrdl, the function was found because the C compiler links with the C library.
Note that Chris Young’s comment about C99 and ‘implicit int’ is accurate, but the rule about ‘variable arguments functions must have a prototype in scope’ applies to both C89 and C99. Most compilers do not work in a strict C99 compatibility mode by default because there is too much code that would not compile like that.
Chris Young commented:
Chris is, of course, correct. There were two ‘implicit declaration’ features removed from the C99 standard. The foreword to the standard lists them as:
intI was not thinking (and hence not writing) clearly enough. Nevertheless, both C89 and C99 require a prototype in scope for functions that take a variable number of arguments.
To illustrate:
Without the first line, this is a correct C89 fragment with an implicit declaration of the function
pqr()as a function that returns an integer (with unspecified arguments). If the first line is replaced byextern pqr();, then this is a correct C89 fragment with an explicit declaration ofpqr()as a function that returns an integer (with unspecified arguments), but the return type is ‘implicitint‘. As written, the function is explicitly declared and has an explicitintreturn type – but it still has unspecified arguments. I believe that is valid C99 – albeit not wholly desirable. Certainly, GCC (3.4.4) accepts it with the options ‘-std=c99 -pedantic‘. Ideally, the function declaration should include the full prototype. (And, ifpqr()were defined with ellipsis, that prototype would be required in theory!)