I am kind of new to C (I have prior Java, C#, and some C++ experience). In C, is it necessary to declare a function prototype or can the code compile without it? Is it good programming practice to do so? Or does it just depend on the compiler? (I am running Ubuntu 9.10 and using the GNU C Compiler, or gcc, under the Code::Blocks IDE)
-
Related: [Are prototypes required for all functions in C89, C90 or C99?](http://stackoverflow.com/q/434763/183120) – legends2k Feb 03 '14 at 08:25
10 Answers
It is never required to declare a prototype for a function in C, neither in "old" C (including C89/90) nor in new C (C99). However, there's a significant difference between C89/90 and C99 with regard to function declarations.
In C89/90 it was not necessary to declare a function at all. If the function is not declared at the point of the call, the compiler "guesses" (infers) the declaration implicitly from the types of the arguments passed in the call and assumes that the return type is int
.
For example
int main() {
int i = foo(5);
/* No declaration for `foo`, no prototype for `foo`.
Will work in C89/90. Assumes `int foo(int)` */
return 0;
}
int foo(int i) {
return i;
}
In C99 every function that you call must be declared before point of the call. However, it is still not necessary to declare it with a prototype specifically. A non-prototype declaration will work as well. This means that in C99 the "implicit int
" rule no longer works (for inferred function return types, in this case), but parameter types can still be guessed from the argument types if function is declared without a prototype.
The previous example will not compile in C99, since foo
is not declared at the point of the call. Yet, you can add a non-prototype declaration
int foo(); /* Declares `foo`, but still no prototype */
int main() {
int i = foo(5);
/* No prototype for `foo`, although return type is known.
Will work in C99. Assumes `int foo(int)` */
return 0;
}
...
and end up with valid C99 code.
Nevertheless, it is always a good practice to declare a prototype for the function before you call it.
An additional note: I said above that it is never required to declare a function prototype. In fact, for some functions it is a requirement. In order to properly call a variadic function in C (printf
for example) the function must be declared with a prototype before the point of the call. Otherwise, the behavior is undefined. This applies to both C89/90 and C99.

- 730,956
- 141
- 904
- 1,278

- 312,472
- 42
- 525
- 765
-
7
-
*"will not compile in C99"* -- no compiler errors (only warnings) on gcc and clang with `-std=c99` on my system. [ideone also compiles it](https://ideone.com/2wIPjm) – jfs Oct 22 '17 at 17:01
-
6@jfs GCC documentation comes with help: "(...) to obtain all the diagnostics required by the standard, you should also specify `-pedantic` (or `-pedantic-errors` if you want them to be errors rather than warnings) (...)". – Przemek Jun 18 '18 at 13:47
-
@Przemek what is your point? Are you trying to say that "-std=c99" is not enough to declare it "will compile in c99"? Perhaps you are right, it depends on what someone is trying to say exactly and your interpretation may be closer to what the author of the answer meant by "will not compile in C99" – jfs Jun 20 '18 at 14:36
-
1@jfs, because in GCC "-std=c99" means c99 standard plus gnu extensions. The problem might compile because of GNU extensions allows it. You need to add "-Wpedantic" for GCC to issue all the warnings demanded by strict ISO C. – MaxPlankton Apr 21 '20 at 20:26
-
*"The `-pedantic` option causes gcc to print required diagnostics for violations of constraints and syntax rules. In some cases, those diagnostics are merely warnings -- and there's no easy way to distinguish between those warnings and other warnings that aren't required by the language. Replace `-pedantic` by `-pedantic-errors` to cause gcc to treat language violations as fatal errors."* —— **From** https://stackoverflow.com/a/14737642/5983841 – Rick Jun 11 '22 at 14:18
In ANSI C (meaning C89 or C90), you do not have to declare a function prototype; however, it is a best practice to use them. The only reason the standard allows you to not use them is for backward compatibility with very old code.
If you do not have a prototype, and you call a function, the compiler will infer a prototype from the parameters you pass to the function. If you declare the function later in the same compilation unit, you'll get a compile error if the function's signature is different from what the compiler guessed.
Worse, if the function is in another compilation unit, there's no way to get a compilation error, since without a a prototype there's no way to check. In that case, if the compiler gets it wrong, you could get undefined behavior if the function call pushes different types on the stack than the function expects.
Convention is to always declare a prototype in a header file that has the same name as the source file containing the function.
In C99 or C11, standard C requires a function declaration in scope before you call any function. Many compilers do not enforce this restriction in practice unless you force them to do so.

- 730,956
- 141
- 904
- 1,278

- 1,140
- 8
- 10
-
1You will not necessarily get a "compile error", if the actual function type is different from the inferred one. This is undefined behavior in C, but not a constraint violation. – AnT stands with Russia Apr 04 '10 at 17:18
-
1You're right, should have been more specific, what I meant was that most compilers will throw a warning. – user308405 Apr 04 '10 at 17:32
-
2In C99, you do need a function declaration - though I suppose it does not have to be a prototyped declaration. C90 (C89) was a lot more lax about it. Note that you do need a prototype in scope if the function uses 'variable arguments' - even in C89/C90. – Jonathan Leffler Apr 04 '10 at 17:42
-
@JonathanLeffler In both C99 implementations I've used (gcc, clang), a missing declaration flags a warning, not an error, even though the declaration is mandatory. – JeremyP Jan 09 '14 at 16:48
-
2@JeremyP: the compilers are still (too?) forgiving by default, largely because of the legacy code bases that still have to be updated. The compilers don't enforce the letter of the standard unless you force their hand (`-Werror`, for example, and perhaps `-pedantic` or `-Wold-style-definition` or `-Wold-style-declaration` or `-Wmissing-prototypes` or `-Wstrict-prototypes` or all (or most) of the above). I usually use `-std=c11` and all those except `-pedantic`, but I make sure that POSIX or related `#define`'s are active. I don't write `#define _GNU_SOURCE` or `#define _BSD_SOURCE` very often. – Jonathan Leffler Jan 09 '14 at 17:45
-
1@JonathanLeffler: I've seen some systems which use different default calling conventions for non-prototyped functions than are used for prototyped functions that take arguments, and *also* use different link-time naming. If a function has a prototype and isn't marked as using stack-based arguments, attempting to call it without a visible declaration will result in a link-time error. – supercat May 28 '15 at 16:48
-
@supercat: can you identify the systems. It isn't orthodox C for functions to be renamed (or otherwise unlinkable) when mis-invoked. C++ can (and does) rename functions, of course, in order to provide type-safe linking. Are you sure it wasn't using a C++ compiler? – Jonathan Leffler May 28 '15 at 16:53
-
@JonathanLeffler: One that comes to mind is the Archimedes compiler for the 8051. It is extremely orthodox for C functions to be renamed somewhat (quite commonly by prepending a `_`) so as to prevent naming conflicts with things like assembler keywords, CPU registers, compiler-generated labels, etc. – supercat May 28 '15 at 17:21
-
@JonathanLeffler: BTW, I think using name prefixes to identify calling conventions is a good pattern; adding such a pattern to the ARM ABI would allow code which use the CPU for floating-point math (and doesn't require an FPU) to inter-operate smoothly with code that expects floating-point values to be passed in FPU registers. Have methods which which expect things in FPU registers apply a prefix to their name; when compiling such a function, include a "weak" definition for a function named without that prefix which loads FPU registers with values passed elsewhere and calls... – supercat May 28 '15 at 17:59
-
...the one with the prefix. Have code which would naturally have things in the FPU registers call the specially-named one, but include a weak definition for a specially-named function that adjusts the parameter format and calls the non-specially named one. Such an approach would allow code written to use an FPU to call directly to methods that expect an FPU, and vice versa, without added overhead, and would allow calls between code expecting different calling conventions to be automatically dispatched through stubs that would fix the parameters as needed. – supercat May 28 '15 at 18:05
it's not a must, if the function is defined before its use.

- 11,925
- 4
- 39
- 52
-
-
1Just the logical order of code in the file, or the fuction is defined in other file. – Drakosha Feb 22 '12 at 17:37
-
In fact new-style definition of a function is a prototype as much as it is declaration. If the definition happens before any use, another prototype without body would be pointless. – Przemek Jun 18 '18 at 13:58
It is not required, but it is bad practice not to use prototypes.
With prototypes, the compiler can verify you are calling the function correctly (using the right number and type of parameters).
Without prototypes, it's possible to have this:
// file1.c
void doit(double d)
{
....
}
int sum(int a, int b, int c)
{
return a + b + c;
}
and this:
// file2.c
// In C, this is just a declaration and not a prototype
void doit();
int sum();
int main(int argc, char *argv[])
{
char idea[] = "use prototypes!";
// without the prototype, the compiler will pass a char *
// to a function that expects a double
doit(idea);
// and here without a prototype the compiler allows you to
// call a function that is expecting three argument with just
// one argument (in the calling function, args b and c will be
// random junk)
return sum(argc);
}

- 74,869
- 16
- 134
- 187
-
@NeilButterworth: When compiling file2.c the definition of doit (which is in file1.c) is not visible. – sepp2k Apr 04 '10 at 17:09
-
@NeilButterworth - I'll reformat, but the comments `// file1.c` and `// file2.c` are meant to imply these are different files. When compiling file2.c, the compiler will not have seen the definition in file1.c – R Samuel Klatchko Apr 04 '10 at 17:10
-
In C, if we do not declare a function prototype and use the function definition, there is no problem and the program compiles and generates the output if the return type of the function is "integer". In all other conditions the compiler error appears. The reason is, if we call a function and do not declare a function prototype then the compiler generates a prototype which returns an integer and it searches for the similar function definition. if the function prototype matches then it compiles successfully. If the return type is not integer then the function prototypes do not match and it generates an error. So it is better to declare function prototype in the header files.
C allows functions to be called even though they have not previously been declared, but I strongly recommend you to declare a prototype for all functions before using them so that the compiler can save you if you use the wrong arguments.

- 67,989
- 17
- 150
- 217
You should put function declarations in the header file (X.h) and the definition in the source file (X.c). Then other files can #include "X.h"
and call the function.

- 1,107
- 6
- 10
-
-
Can someone explain why this is a bad idea, I was always under the impression this was standard practice? The only issue that occurs from this is circular inclusion. But, otherwise if you plan your includes you won't run into that problem. – Natalie Adams Apr 04 '10 at 17:32
-
2Because not all functions are meant to be public. If you have static void foo() defined _after_ static int bar(), and bar calls foo .. well :) Why would you prototype functions that aren't exposed in a public header? I'm not the one who down voted, though. – Tim Post Apr 04 '10 at 18:35
-
1I assume the downvote (not from me) was because this doesn't address the question. – Apr 04 '10 at 18:41
-
@Tim, bar can call foo because the compiler will already know about it from the prototype. Unless this is untrue in C, it should be true in C++. Can you post an example so maybe we can get a better idea of what you mean? @Neil Even though it doesn't answer the question directly it does relate to a "best practice" that is related to the question which I don't see as a need to down vote. Maybe not an upvote, but it isn't something that I would want removed or is unnecessary. – Natalie Adams Apr 04 '10 at 22:15
-
@Tim maybe because a programmer would like to have all functions from a c file in a descriptive way in its header? – Pithikos Oct 27 '11 at 07:02
It's not absolutely necessary to declare a function for the calling code to compile. There are caveats though. Undeclared function is assumed to return int
and compiler will issue warnings first about function being undeclared and then about any mismatches in return type and parameter types.
Having said that it's obvious that declaring functions properly with prototypes is a much better practice.

- 82,306
- 11
- 110
- 171
Select ‘Options’ menu and then select ‘Compiler | C++ Options’. In the dialog box that pops up, select ‘CPP always’ in the ‘Use C++ Compiler’ options. Again select ‘Options’ menu and then select ‘Environment | Editor’. Make sure that the default extension is ‘C’ rather than ‘CPP’.
-
1This does not seem to answer the question that was asked but some loosely related question about a specific IDE. – Jonathan Leffler Feb 27 '15 at 05:58