3

Possible Duplicate:
Why #include <stdio.h> is not required to use printf()?

Both printf and scanf have been declared in stdio.h. But they work even without that, dropping just a warning message? What's the theory behind this?

Community
  • 1
  • 1
1s2a3n4j5e6e7v
  • 1,243
  • 3
  • 15
  • 29

6 Answers6

14

Calling a function without declaring it will create an implicit declaration based on the parameters you give and an assumed return type of int. This lets it get past the compilation stage, since the function could exist somewhere else that isn’t known until link time — C didn’t always have function prototypes, so this is for backwards compatibility. (In C++, it’s an error, and in C99 GCC gives a warning.)

If you look at the man page (on FreeBSD and Darwin, at least) for printf, scanf, puts, etc., it says that it comes from the “Standard C Library (libc, -lc)”. GCC implicitly links with the standard C library. If you link with the -nostdlib flag, you'll get the “undefined symbols” error that you're expecting.

(In fact, when I turn off libc, my GNU/Linux system complains about the absence of _start as well, and my OpenBSD system complains about _start, __guard, and __stack_smash_handler.)

Josh Lee
  • 171,072
  • 38
  • 269
  • 275
6

By default the C compiler assumes that functions that do not have a declaration return an int and does not check the parameters to the function. It it can find a declaration then the compiler will do checking of the parameters

mmmmmm
  • 32,227
  • 27
  • 88
  • 117
1

When your compiler warns you, you should figure out what that means, and fix the problem. The fact that a compiler warns you about invalid code and then goes on to compile the code means little.

As to why they work, the answer is "bad luck". It only seems to work for you, but it is not guaranteed to according to the C standard.

Alok Singhal
  • 93,253
  • 21
  • 125
  • 158
  • He said he's getting a warning; clearly he's running with warnings enabled. – T.J. Crowder Feb 04 '10 at 11:08
  • @T.J. - Not necessarily. Many compilers will issue warnings unconditionally for some common errors. Cranking up the warnings, however, can make some errors clearer, and help you catch them sooner. – Chris Lutz Feb 04 '10 at 11:21
  • I guess I parsed "dropping a warning" wrongly. Not the best phrase, but I should have been more careful. Thanks. – Alok Singhal Feb 04 '10 at 11:22
1

Because in C you do not have to provide prototype of functions, there is standard conversion of passing parameters, thus if you pass parameters of same types it should work.

Back to early days of C, there where no prototypes at all, they where added later.

Note: this is different in C++, calling function without prototype on C++ would lead to compilation error.

Artyom
  • 31,019
  • 21
  • 127
  • 215
  • Except that it's not allowed to call variadic functions (like `printf` and `scanf`) without a prototype in scope - that's undefined behaviour. – caf Feb 04 '10 at 11:31
1

In C, if you don't declare a function, and then you use it anyway, by default it returns type int. (Incidentally that is also the return type of these functions.) Also, in the olden days (pre-ANSI) I believe it didn't matter whether or not you specified the names or types of arguments to functions in a prototype. So even though for your case printf() is declared as int printf(); you can pass it arguments and it won't complain. I'm not sure that there's any guarantee in the standard that a function declared as such will have the same calling convention as int (*)(const char *, ...), but for most compilers I'm going to guess that the answer is yes. So it worked.

Note the rules are different for C++. If you compiled your code as C++ my guess is the compiler wouldn't accept it.

asveikau
  • 39,039
  • 2
  • 53
  • 68
0

Th GCC compiler, which I suspect you are using, actually "knows" about some of the commonly used functions like printf, and has special code to process them. This allows it to do things like checking printf's format string, which are not required by the C or C++ standards.

  • I really doubt this is the explanation. I'm pretty sure g++ will reject use of printf() if printf() has no prototype. – asveikau Feb 04 '10 at 11:16
  • 1
    gcc will accept it (with a warning), g++ won't. And GCC does have special code to handle printf - see -Wformat in the manual. –  Feb 04 '10 at 11:18
  • gcc tries to compile C code, while g++ compiles C++. Implicit function declaration (as jleedev describes) is legal only in C, not C++. Try using function int Neil_Butterworth(int) and declaring it *after* using. On my compiler (cygwin, gcc 3.4.4) it works. Well, either gcc 'knows' you, or it is implicit function declaration :-) – Tadeusz Kopec for Ukraine Feb 04 '10 at 11:44
  • The C compiler doesn't know anything, it will infer (and hopefully warn) and assume a standard int return value. – stsquad Feb 04 '10 at 11:57