Search code examples
clanguage-lawyerstdio

Writing prototypes instead of #include <stdio.h>


For example, here is a "hello, world" program without stdio.h included:

int puts(const char *str);

int main(void)
{
    puts("hello, world");
}

I even think this can be a good programming style when my program gets longer and longer, for all functions called are listed at the beginning explicitly.

So my question is: Besides providing prototypes for standard library functions, what else does #include <stdio.h> do?


Solution

  • The (non-normative) Appendix J.2 of the C11 standard draft lists the following among examples of undefined behaviour:

    — A function, object, type, or macro that is specified as being declared or defined by some standard header is used before any header that declares or defines it is included (7.1.2)

    However, as pointed out by Keith Thompson, the 7.1.4p2 says:

    2 Provided that a library function can be declared without reference to any type defined in a header, it is also permissible to declare the function and use it without including its associated header.

    Thus using puts without including <stdio.h> can indeed be done in standard-conforming manner. However, you cannot declare fputs, since it requires a pointer-to-FILE as an argument, which you cannot do in a strictly conforming manner.

    In addition, puts might also be a macro in presence of <stdio.h> and expand to something faster in the presence of the header.

    All in all, the number of functions that can be declared properly without including headers is not that large. As for the functions that use some types from the headers - if you're asking with language-lawyer tag about C, the answer comes from the standard and the standard is rather outspoken about this: don't do it, or your program will not be strictly conforming, period.