Are function declarations/prototypes necessary in C99 ?
I am currently defining my functions in a header file and #include-ING it in the main file. Is this OK in C99 ?
Why do most programmers declare/prototype the function before main() and define it after main() ? Isn't it just easier to define them before main and avoid all the declarations/prototypes ?
Contents of header.h file:
int foo(int foo)
{
// code
return 1;
}
Contents of main file:
#include <stdio.h>
#include "header.h"
int main(void)
{
foo(1);
return 0;
}
How and where to prototype and define a function in C :
Your function is used only in a specific .c file :
Define it static in the .c file. The function will only be visible and compiled for this file.
Your function is used in multiple .c files :
Choose an appropriate c file to host your definition (All foo related functions in a foo.c file for example), and have a related header file to have all non-static (think public) functions prototyped. The function will be compiled only once, but visible to any file that includes the header files. Everything will be put together at link time. Possible improvement : always make the related header file, the first one included in its c file, this way, you will be sure that any file can include it safely without the need of other includes to make it work, reference : Large Scale C++ projects (Most of the rules apply to C too).
Your function is inlinable (are you sure it is ?) :
Define the function static inline in an appropriate header file. The compiler should replace any call to your function by the definition if it is possible (think macro-like).
The notion of before-after another function (your main function) in c is only a matter of style. Either you do :
static int foo(int foo)
{
// code
return 1;
}
int main(void)
{
foo(1);
return 0;
}
Or
static int foo(int foo);
int main(void)
{
foo(1);
return 0;
}
static int foo(int foo)
{
// code
return 1;
}
will result in the same program. The second way is prefered by programmers because you don`t have to reorganize or declare new prototypes every time you declare a new function that use the other ones. Plus you get a nice list of every functions declared in your file. It makes life easier in the long run for you and your team.
People typically do it because it's easier to do with multiple files. If you declare in a header then you can just #include that header anywhere you need those functions. If you define them in a header and then include in another translation unit, bang.
Function declarations are required in C99. Function prototypes are not required in C99.
Declaring functions before the point of the call and defining them after the point of the call is a popular approach to structuring the program code. However, this is in no way what the "most" programmers do. On the contrary, a more popular approach is to define function before the point of the first call, in which case the separate declaration is not necessary. This approach requires less maintenance, which is why it is more popular than what you describe.
Separate declarations/definitions are normally used with external functions only, i.e. with functions used across several translation units. Such functions are declared in header files and defined in implementation files.
You should only ever define inline functions in headers. Although you can have extern inline functions, the common case is static inline.
Rule of thumb for header files:
function declarations should be extern
function definitions should be static inline
variable declarations should be extern
variable definitions should be static const
As C. Ross asked for it, here's reasoning behind it: A resource with external linkage should only ever be defined once[1]. It follows that definitions should not reside in header files, which are intended to be included in more than one place.
Having static definitions in header files won't lead to any problems, but is generally frowned upon because the code has to be compiled more than once and will be present in different object files, which will increase the executable size (assuming the linker isn't smart enough to figure out the code duplication).
The common exceptions to this rule are constants and inline functions, which are supposed to be visible to the compiler in each translation unit to make further optimizations possible.
Note: [1] This does not apply to inline functions with external linkage, but as it's unspecified which of the multiple definitions of an inline function will be used in the evaluation of a function designator, they are mostly useless
Your approach is fine for small programs. Header files are meant for declarations and constant definitions - they provide an interface to the program they "encapsulate". Headers are meant as an interface for other program units.
In case you have more .c files, forward declarations and header files are necessary, because a C function can be defined only once for the whole program (search for one definition rule), even though you may use the function anywhere (in any .c file). If you defined it in a header, it would get included in all .c files you use it in and result in multiple definitions.
It's quicker to do like that, but I personally prefer to have the main function at the beginning of the main file, and put the other functions in other files or below main.
Note that in your example you should avoid declaring foo() in a header file: you won't be able to include it in two different source files. Declare it in the C file containing main(); you won't need to define it elsewhere unless you're referring to it from some other files.
Yes, it is easier to define them before main. If you only want to use these functions from within the file, a prototype is not necessary. In that case however, you can also prepend the "static" keyword before the function definition. (In the C file.) That will ensure the function is not visible to other files. (At link time.)
Do not put static keywords in include files.
You should always prototype.
The reasons for this are;
methodical prototyping produces a succinct list in header files of the functions in the code - this is invaluable to future readers
in anything but the simplest projects, many functions will not have visibility prior to main.
main should be the first function in its file; it's easier for the reader, since we read down, not up
Why do most programmers declare/prototype the function before main() and define it after main() ?
Merely because most humans read sequentially. Start a story from the beginning, not the middle. Not necessary, just intuitive.
Of course if the code being prototyped is in a separate compilation unit, the prototypes are necessary.
It is always a good practice to declare the functions in either before main or in a separate header file which will be included in other c files where we have used that function. By doing this we can easily identify all the functions declared/defined in that .C or .H files. And we should use extern key word before declaring the function in header file.
Related
My question is about when a function should be referenced with the extern keyword in C.
I am failing to see when this should be used in practice. As I am writing a program all of the functions that I use are made available through the header files I have included. So why would it be useful to extern to get access to something that was not exposed in the header file?
I could be thinking about how extern works incorrectly, and if so please correct me.
Also.. Should you extern something when it is the default declaration without the keyword in a header file?
extern changes the linkage. With the keyword, the function / variable is assumed to be available somewhere else and the resolving is deferred to the linker.
There's a difference between extern on functions and on variables.
For variables it doesn't instantiate the variable itself, i.e. doesn't allocate any memory. This needs to be done somewhere else. Thus it's important if you want to import the variable from somewhere else.
For functions, this only tells the compiler that linkage is extern. As this is the default (you use the keyword static to indicate that a function is not bound using extern linkage) you don't need to use it explicitly.
extern tells the compiler that this data is defined somewhere and will be connected with the linker.
With the help of the responses here and talking to a few friends here is the practical example of a use of extern.
Example 1 - to show a pitfall:
stdio.h:
int errno;
myCFile1.c:
#include <stdio.h>
// Code using errno...
myCFile2.c:
#include <stdio.h>
// Code using errno...
If myCFile1.o and myCFile2.o are linked, each of the c files have separate copies of errno. This is a problem as the same errno is supposed to be available in all linked files.
Example 2 - The fix.
stdio.h:
extern int errno;
stdio.c:
int errno;
myCFile1.c:
#include <stdio.h>
// Code using errno...
myCFile2.c:
#include <stdio.h>
// Code using errno...
Now if both myCFile1.o and MyCFile2.o are linked by the linker they will both point to the same errno. Thus, solving the implementation with extern.
It has already been stated that the extern keyword is redundant for functions.
As for variables shared across compilation units, you should declare them in a header file with the extern keyword, then define them in a single source file, without the extern keyword. The single source file should be the one sharing the header file's name, for best practice.
Many years later, I discover this question. After reading every answer and comment, I thought I could clarify a few details... This could be useful for people who get here through Google search.
The question is specifically about using extern functions, so I will ignore the use of extern with global variables.
Let's define 3 function prototypes:
// --------------------------------------
// Filename: "my_project.H"
extern int function_1(void);
static int function_2(void);
int function_3(void);
The header file can be used by the main source code as follows:
// --------------------------------------
// Filename: "my_project.C"
#include "my_project.H"
void main(void) {
int v1 = function_1();
int v2 = function_2();
int v3 = function_3();
}
int function_2(void) return 1234;
In order to compile and link, we must define function_2 in the same source code file where we call that function. The two other functions could be defined in different source code *.C or they may be located in any binary file (*.OBJ, *.LIB, *.DLL), for which we may not have the source code.
Let's include again the header my_project.H in a different *.C file to understand better the difference. In the same project, we add the following file:
// --------------------------------------
// Filename: "my_big_project_splitted.C"
#include "my_project.H"
void old_main_test(void){
int v1 = function_1();
int v2 = function_2();
int v3 = function_3();
}
int function_2(void) return 5678;
int function_1(void) return 12;
int function_3(void) return 34;
Important features to notice:
When a function is defined as static in a header file, the compiler/linker must find an instance of a function with that name in each module which uses that include file.
A function which is part of the C library can be replaced in only one module by redefining a prototype with static only in that module. For example, replace any call to malloc and free to add memory leak detection feature.
The specifier extern is not really needed for functions. When static is not found, a function is always assumed to be extern.
However, extern is not the default for variables. Normally, any header file that defines variables to be visible across many modules needs to use extern. The only exception would be if a header file is guaranteed to be included from one and only one module.
Many project managers would then require that such variable be placed at the beginning of the module, not inside any header file. Some large projects, such as the video game emulator "Mame" even require that such variables appears only above the first function using them.
In C, extern is implied for function prototypes, as a prototype declares a function which is defined somewhere else. In other words, a function prototype has external linkage by default; using extern is fine, but is redundant.
(If static linkage is required, the function must be declared as static both in its prototype and function header, and these should normally both be in the same .c file).
A very good article that I came about the extern keyword, along with the examples: http://www.geeksforgeeks.org/understanding-extern-keyword-in-c/
Though I do not agree that using extern in function declarations is redundant. This is supposed to be a compiler setting. So I recommend using the extern in the function declarations when it is needed.
If each file in your program is first compiled to an object file, then the object files are linked together, you need extern. It tells the compiler "This function exists, but the code for it is somewhere else. Don't panic."
All declarations of functions and variables in header files should be extern.
Exceptions to this rule are inline functions defined in the header and variables which - although defined in the header - will have to be local to the translation unit (the source file the header gets included into): these should be static.
In source files, extern shouldn't be used for functions and variables defined in the file. Just prefix local definitions with static and do nothing for shared definitions - they'll be external symbols by default.
The only reason to use extern at all in a source file is to declare functions and variables which are defined in other source files and for which no header file is provided.
Declaring function prototypes extern is actually unnecessary. Some people dislike it because it will just waste space and function declarations already have a tendency to overflow line limits. Others like it because this way, functions and variables can be treated the same way.
Functions actually defined in other source files should only be declared in headers. In this case, you should use extern when declaring the prototype in a header.
Most of the time, your functions will be one of the following (more like a best practice):
static (normal functions that aren't
visible outside that .c file)
static inline (inlines from .c or .h
files)
extern (declaration in headers of the
next kind (see below))
[no keyword whatsoever] (normal
functions meant to be accessed using
extern declarations)
When you have that function defined on a different dll or lib, so that the compiler defers to the linker to find it. Typical case is when you are calling functions from the OS API.
I've seen a few questions addressing this general topic, but I'm still unsure exactly what the correct approach is for ISO C, and how that may or may not vary from GNU C.
If I have some function inline void foo() in file.h defined with the inline keyword, should I also declare that function in file.c as extern void foo();? Assume that multiple .c files will include file.h.
From what I've read the answer seems to be "yes" and have something to do with how the compiler looks for definitions emitted by other translation units, but to be honest I don't fully understand the implications.
I'm working on a project right now that has a lot of functions declared inline within the header files, and none of those functions are declared in the corresponding .c files. Everything compiles without gcc complaining, but is this approach actually correct?
Yes, if you use inline without static, there needs to be an actual external definition of the function somewhere in case the compiler declines to inline it in one or more places. The canonical way to do that is to make a source file containining (using your example names) nothing but:
#include "file.h"
extern void foo();
Personally, I find extern inline semantics in C confusing and messy, and prefer to avoid them entirely by making all inline functions static. Of course this wastes space with multiple instantiations of the function if the compiler declines to inline, but you should not be doing this with functions of nontrivial size anyway.
inline means the compiler will expand that function where it is used in the code (instead of calling it as a function). That means that an inline definition in a header file with the function implementation in a .c file makes no sense, as wherever you include the header in another .c file the function can't be expanded inline as its code implementation is not known.
So you should keep the inline function and its code implementation in the header file.
I would like to write a C library with fast access by including just header files without using compiled library. For that I have included my code directly in my header file.
The header file contains:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#ifndef INC_TEST_H_
#define INC_TEST_H_
void test(){
printf("hello\n");
}
#endif
My program doesn't compile because I have multiple reference to function test(). If I had a correct source file with my header it works without error.
Is it possible to use only header file by including code inside in a C app?
Including code in a header is generally a really bad idea.
If you have file1.c and file2.c, and in each of them you include your coded.h, then at the link part of the compilation, there will be 2 test functions with global scope (one in file1.c and the other one in file2.c).
You can use the word "static" in order to say that the function will be restricted so it is only visible in the .c file which includes coded.h, but then again, it's a bad idea.
Last but not least: how do you intend to make a library without a .so/.a file? This is not a library; this is copy/paste code directly in your project.
And when a bug is found in your "library", you will be left with no solution apart correcting your code, redispatch it in every project, and recompile every project, missing the very point of a dynamic library: The ability to "just" correct the library without touching every program using it.
If I understand what you're asking correctly, you want to create a "library" which is strictly source code that gets #incuded as necessary, rather than compiled separately and linked.
As you have discovered, this is not easy when you're dealing with functions - the compiler complains of multiple definitions (you will have the same problem with object definitions).
You have a couple of options at this point.
You could declare the function static:
static void test( void )
{
...
}
The static keyword limits the function's visibility to the current translation unit, so you don't run into multiple definition errors at link time. It means that each translation unit is creating its own separate "instance" of the function, leading to a bit of code bloat and slightly longer build times. If you can live with that, this is the easiest solution.
You could use a macro in place of a function:
#define TEST() (printf( "hello\n" ))
except that macros are not functions and do not behave like functions. While macro-based "libraries" do exist, they are not trivial to implement correctly and require quite a bit of thought. Remember that macro arguments are not evaluated, they're just expanded in place, which can lead to problems if you pass expressions with side effects. The classic example is:
#define SQUARE(x) ((x)*(x))
...
y = SQUARE(z++);
SQUARE(z++) expands to ((z++)*(z++)), which leads to undefined behavior.
Separate compilation is a Good Thing, and you should not try to avoid it. Doing everything in one source file is not scalable, and leads to maintenance headaches.
My program do not compiled because I have multiple reference to test() function
That is because the .h file with the function is included and compiled in multiple C source files. As a result, the linker encounters the function with global scope multiple times.
You could have defined the function as static, which means it will have scope only for the curent compilation unit, so:
static void test()
{
printf("hello\n");
}
Do I need to declare all functions I use in a .c file in a header file, or can I just declare and define right there in the .c file? If so, does a definition in the .c file in this case count as the declaration also?
Do I need to declare all functions I use in a .c file in a header file,
or can I just declare and define right there in the .c file?
You used "use" in the first question and "define" in the next question. There is a difference.
void foo()
{
bar(10);
}
Here, foo is defined and bar is used. You should declare bar. If you don't declare bar, the compiler makes assumptions about its return type.
You can declare bar in the .c file or add the declaration in a .h file and #include the .h file in the .c file. Whether you use the first method or the second method is up to you. If you use the declaration in more than one .c file, it is better to put that in a .h file.
You can define foo without a declaration.
If so, does a definition in the .c file in this case count as the declaration also?
Every function definition counts as a declaration too.
For the compiler, it does not matter if a declaration occurs in a .h or a .c file, because the compiler sees the preprocessed form.
For the human developer reading and contributing to your code, it is much better (to avoid copy&pasting the same declaration twice) to put the declaration of any function used in more than one translation unit (i.e. .c file) in some #include-d header.
And you can define a function before using it.
BTW, you might even avoid declaring a function that you are calling (it defaults to returning int for legacy purposes), but this is poor taste and obsolete way of coding (and most compilers can emit a warning in that case).
No, it is not necessary.
The reason of the header files is to separate the interface from the implementation. The header declares "what" a class (or whatever is being implemented) will do, while the .c file defines "how" it will perform those features.
This reduces dependencies so that code that uses the header doesn't necessarily need to know all the details of the implementation and any other classes/headers needed only for that. This will reduce compilation times and also the amount of recompilation needed when something in the implementation changes.
The answer to both questions is yes. You can declare c-functions in both header and .c file. Same with definition. However, if you are defining it in header file, you may have slight problems during compilation.
By default functions have external linkage. It means that it is supposed that functions potentially will be used in several compilation units.
However sometimes some auxiliary functions that form implementations of other functions are not designed to be used in numerous compilation units. Such functions declared with keyword static have internal linkage.
Usually they are declared and defined inside some .c module and are not visible in other compilation units.
One occasion that requires functions to be declared in a separate header is when one is creating a library for other developers to use. Some libraries are distributed as closed source and they are provided to you as a library file (*.dll / *.so ...) and a header.
The header file would contain declarations of all publicly accessible functions and definitions of all publicly required structures, enums and datatypes etc.
Without this header file the 3rd party library user would not know how to interface with the library file and thus would not be able to link against it.
But for small, trivial C programs that are not intended for use by other people, no you can just dump everything into a C file and build it. Although you might curse yourself years later when you need to maintain that code :)
My question is about when a function should be referenced with the extern keyword in C.
I am failing to see when this should be used in practice. As I am writing a program all of the functions that I use are made available through the header files I have included. So why would it be useful to extern to get access to something that was not exposed in the header file?
I could be thinking about how extern works incorrectly, and if so please correct me.
Also.. Should you extern something when it is the default declaration without the keyword in a header file?
extern changes the linkage. With the keyword, the function / variable is assumed to be available somewhere else and the resolving is deferred to the linker.
There's a difference between extern on functions and on variables.
For variables it doesn't instantiate the variable itself, i.e. doesn't allocate any memory. This needs to be done somewhere else. Thus it's important if you want to import the variable from somewhere else.
For functions, this only tells the compiler that linkage is extern. As this is the default (you use the keyword static to indicate that a function is not bound using extern linkage) you don't need to use it explicitly.
extern tells the compiler that this data is defined somewhere and will be connected with the linker.
With the help of the responses here and talking to a few friends here is the practical example of a use of extern.
Example 1 - to show a pitfall:
stdio.h:
int errno;
myCFile1.c:
#include <stdio.h>
// Code using errno...
myCFile2.c:
#include <stdio.h>
// Code using errno...
If myCFile1.o and myCFile2.o are linked, each of the c files have separate copies of errno. This is a problem as the same errno is supposed to be available in all linked files.
Example 2 - The fix.
stdio.h:
extern int errno;
stdio.c:
int errno;
myCFile1.c:
#include <stdio.h>
// Code using errno...
myCFile2.c:
#include <stdio.h>
// Code using errno...
Now if both myCFile1.o and MyCFile2.o are linked by the linker they will both point to the same errno. Thus, solving the implementation with extern.
It has already been stated that the extern keyword is redundant for functions.
As for variables shared across compilation units, you should declare them in a header file with the extern keyword, then define them in a single source file, without the extern keyword. The single source file should be the one sharing the header file's name, for best practice.
Many years later, I discover this question. After reading every answer and comment, I thought I could clarify a few details... This could be useful for people who get here through Google search.
The question is specifically about using extern functions, so I will ignore the use of extern with global variables.
Let's define 3 function prototypes:
// --------------------------------------
// Filename: "my_project.H"
extern int function_1(void);
static int function_2(void);
int function_3(void);
The header file can be used by the main source code as follows:
// --------------------------------------
// Filename: "my_project.C"
#include "my_project.H"
void main(void) {
int v1 = function_1();
int v2 = function_2();
int v3 = function_3();
}
int function_2(void) return 1234;
In order to compile and link, we must define function_2 in the same source code file where we call that function. The two other functions could be defined in different source code *.C or they may be located in any binary file (*.OBJ, *.LIB, *.DLL), for which we may not have the source code.
Let's include again the header my_project.H in a different *.C file to understand better the difference. In the same project, we add the following file:
// --------------------------------------
// Filename: "my_big_project_splitted.C"
#include "my_project.H"
void old_main_test(void){
int v1 = function_1();
int v2 = function_2();
int v3 = function_3();
}
int function_2(void) return 5678;
int function_1(void) return 12;
int function_3(void) return 34;
Important features to notice:
When a function is defined as static in a header file, the compiler/linker must find an instance of a function with that name in each module which uses that include file.
A function which is part of the C library can be replaced in only one module by redefining a prototype with static only in that module. For example, replace any call to malloc and free to add memory leak detection feature.
The specifier extern is not really needed for functions. When static is not found, a function is always assumed to be extern.
However, extern is not the default for variables. Normally, any header file that defines variables to be visible across many modules needs to use extern. The only exception would be if a header file is guaranteed to be included from one and only one module.
Many project managers would then require that such variable be placed at the beginning of the module, not inside any header file. Some large projects, such as the video game emulator "Mame" even require that such variables appears only above the first function using them.
In C, extern is implied for function prototypes, as a prototype declares a function which is defined somewhere else. In other words, a function prototype has external linkage by default; using extern is fine, but is redundant.
(If static linkage is required, the function must be declared as static both in its prototype and function header, and these should normally both be in the same .c file).
A very good article that I came about the extern keyword, along with the examples: http://www.geeksforgeeks.org/understanding-extern-keyword-in-c/
Though I do not agree that using extern in function declarations is redundant. This is supposed to be a compiler setting. So I recommend using the extern in the function declarations when it is needed.
If each file in your program is first compiled to an object file, then the object files are linked together, you need extern. It tells the compiler "This function exists, but the code for it is somewhere else. Don't panic."
All declarations of functions and variables in header files should be extern.
Exceptions to this rule are inline functions defined in the header and variables which - although defined in the header - will have to be local to the translation unit (the source file the header gets included into): these should be static.
In source files, extern shouldn't be used for functions and variables defined in the file. Just prefix local definitions with static and do nothing for shared definitions - they'll be external symbols by default.
The only reason to use extern at all in a source file is to declare functions and variables which are defined in other source files and for which no header file is provided.
Declaring function prototypes extern is actually unnecessary. Some people dislike it because it will just waste space and function declarations already have a tendency to overflow line limits. Others like it because this way, functions and variables can be treated the same way.
Functions actually defined in other source files should only be declared in headers. In this case, you should use extern when declaring the prototype in a header.
Most of the time, your functions will be one of the following (more like a best practice):
static (normal functions that aren't
visible outside that .c file)
static inline (inlines from .c or .h
files)
extern (declaration in headers of the
next kind (see below))
[no keyword whatsoever] (normal
functions meant to be accessed using
extern declarations)
When you have that function defined on a different dll or lib, so that the compiler defers to the linker to find it. Typical case is when you are calling functions from the OS API.