Why use the extern keyword in header in C? [duplicate] - c

This question already has answers here:
How do I use extern to share variables between source files?
(19 answers)
Closed 9 years ago.
Why should I use the extern keyword in the following code:
header.h
float kFloat; // some say I should write 'extern float kFloat;', but why?
file.c
#include <stdio.h>
#include "Header.h"
float kFloat = 11.0f;
main.c
#include <stdio.h>
#include "Header.h"
int main(int argc, const char * argv[])
{
printf("The global var is %.1f\n", kFloat);
return 0;
}
This code works. The global Variable kFloat defaults to external linkage and static lifetime.
Output is:
The global var is 11.0
I don't understand in which case the problem would occur, can anyone give me an example where it would crash?

extern float kFloat;
declares kFloat without defining it.
but:
float kFloat;
also declares kFloat but is a tentative definition of kFloat.
Adding extern just suppresses the tentative definition. In a header file you only want declarations, not definitions.
If the tentative definition is included in several source files, you will end up having multiple definitions of the same object which is undefined behavior in C.

Always put the definition of global variables(like float kFloat;) in the .c file, and put the declarations (like extern float kFloat;) in the header.
Otherwise when multiple .c files include the same header, there will be a multiple definition error.

extern indicates that a variable is defined somewhere in the project (or outside function block) that you want to use. It does not allocate memory for it since you are telling the compiler that this is defined else where.
A variable must be defined once in one of the modules of the program. If there is no definition or more than one, an error is produced, possibly in the linking stage.
Definition refers to the place where the variable is created or assigned storage; declaration refers to places where the nature of the variable is stated but no storage is allocated.
And since it will be accessible elsewhere it needs to be static.

Firstly, it is strange that your code is compiling. It should throw compile time error for double definition of kFloat variable in File.c.
Secondly, if you are trying to use the common variable in two files then it should not be defined in the header.h. You should use extern keyword in header file so that the file which includes the header.h gets to know that it has been defined externally.
Now, you can define the variable globally in any of the c files and then use the variable as a common variable.

Why should I use extern ...?
Well, you shouldn't. Plain and simple. Because you shouldn't use global variables, and they are the only ones that would need the extern keyword.
Whenever you feel tempted to use a global variable, think again. At the absolute maximum, you might need to use a variable with file scope (using the static keyword), typically such a variable would be accompanied by a handful of functions that manipulate/use its value, but the variable itself should not be visible beyond the scope of the file. Usage of global variable only leads to intractably tangled code that is almost impossible to change without introducing a ton of bugs.

Related

Why is extern required for global variable on Linux but not Mac when compiling shared object? [duplicate]

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.

Where can I declare global variable in c program , whether in header or source file [duplicate]

This question already has answers here:
How do I use extern to share variables between source files?
(19 answers)
Closed 6 years ago.
Hi I am a C++ developer now I am doing C programming.
My question is which place is better to declare global variable in c program.
Header or source file (provided my global variable is not used in other files)?
I want that variable like private variable in C++.
Assuming your variable is global and non static.
You need to declare it in a header file. We use extern keyword for this. As pointed out in comments, this keywords is not necessary, but most C users prefer to use it in headers, this is a convention.
stackoverflow.h:
#ifndef STACHOVERFLOW_H
#define STACHOVERFLOW_H
extern int my_var;
#ifndef
And you initialize it in source file. (Use of keyword extern is prohibited if you want to provide an initialization value).
stackoverflow.c
#include "stackoverflow.h"
int my_var = 50;
Do not put initialization value in a header, or you will get a linker error if the header is used at least twice.
Now you can use your variable in any other module by including the header.
main.c
#include <stdio.h>
#include "stackoverflow.h"
int main()
{
printf("my_var = %d\n", my_var);
return 0;
}
Including header "stackoverflow.h" in "stackoverflow.c" is a way to get sure definitions in source file match declarations in header file. This permit to have errors as soon as compilation instead of sometimes cryptic linker errors.
Edit: This is not at all the way to make a variable "private". You have to use a static variable to make it "private". See R Sahu's answer
which place is better to declare a global variable in c program
Answer: In source(*.c) file.
Assume the scenario like, I have declared a variable in a header file. I included this header in two different .c files. After the macro expansion step of compilation, these two files will have the global variable with the same name. So it will throw an error like multiple declarations of the variable during the linking time.
Conclusion:-
Keep all global variable declaration on .c file and put it as static if it is doesn't need in other files.
Add extern declaration of the variable in the corresponding header file if it's needed to access from other files
You should not place global non-constant variables anywhere. Global as in declared with extern and available to your whole project. The need to do this always originates from bad program design, period. This is true for C and C++ both.
The exception is const variables, which are perfectly fine to share across multiple files.
In the case you need file scope variables, they should be declared in the .c file and always as static. Don't confuse these for "globals" because they are local to the translation unit where they are declared. More info about how static file scope variables can make sense.
Also note the C standard future language directions:
Declaring an identifier with internal linkage at file scope without
the static storage class specifier is an obsolescent feature.
So if you don't use static your code might not compile in the next version of the C standard.
If you intend to use the global variables in multiple .c files, it is better to declare them in .h files. However, if you want to keep the variables like private member data of classes in C++, it will be better to provide access to the global data through functions.
Instead of
extern int foo;
Use
int getFoo();
void setFoo(int);
That sort of mimics the private access specifiers for member variables of classes.
Generally what you can do is define the variable in a source file, like int g_foo;, then reference this global in other files with extern, like extern int g_foo; do_sth(g_foo);. You could put the extern int g_foo; declaration in a header file, and include that in other source files. It's not recommend to have definitions of data in header files.
If you want it to be global (external linkage), you should put it in .h file. And this is one of the best practise, I think:
public_header.h
#ifdef YOUR_SOURCE
#define EXTERN
#else
#define EXTERN extern
#endif
EXTERN int global_var;
your_source.c
//your source makes definition for global_var
#define YOUR_SOURCE
#include <public_header.h>
other_source.c
#include <public_header.h> //other sources make declaration for global_var
If you want it to be private (internal linkage), the best solution, I think, is just make definition of it right in your source file instead of header file to prevent the header file is included by another source and then make confuse.
your_souce.c
static int private_var;

Are there any drawbacks to declaring variables in header files without the "extern" keyword? [duplicate]

This question already has answers here:
How do I use extern to share variables between source files?
(19 answers)
Closed 7 years ago.
I've recently begun to realize that the use of the "extern" keyword is highly encouraged. Thus I began to wonder if there is anything wrong with the current (extern-less) way I use header files:
main.c:
#include "main.h"
#include "function.h"
int main(void){
globalvariable = 0;
testfunction();
return 0;
}
main.h:
#ifndef MAIN_H_
#define MAIN_H_
int globalvariable;
#endif /* MAIN_H_ */
function.c:
#include "main.h"
#include "function.h"
void testfunction(){
globalvariable++;
return;
}
function.h:
#ifndef FUNCTION_H_
#define FUNCTION_H_
void testfunction(void);
#endif /* FUNCTION_H_ */
Thus every new source file that needs access to globalvariable simply needs to include main.h.
One obvious drawback to this method is arrays: you can't use {element0, element1, ...} formatting to assign values to an array once it has been declared.
By the way, when I give globalvariable an initial value of zero, am I defining it at that point? Or is memory allocated earlier?
Also, is there an official term for the method I'm using?
The only official term that I know of for the method you are using is "implementation dependent behavior". You will run into all sorts of problems with that method once you start building with different compilers (or possibly even different versions of the same compiler). Some will throw a linker error, but some will accept it (although there's no guarantee exactly how it will be interpreted). I highly recommend that you adopt a more standard approach that compilers will interpret in a predictable way.
The definition for a variable needs to be in a .c file. If you want to access that variable from another .c file, add an extern declaration in a header. This technique is standard C and will be interpreted predictably on any conforming compiler.
To answer your allocation question, memory for all globals is allocated before the program starts running. A global variable takes up space even if it is only used in a subsection of the code that never runs. Your globalvariable = 0; line isn't actually giving the variable an initial value. The C compiler will make sure that all uninitialized global variables are automatically initialized to zero when the program loads. Your code is technically re-assigning the variable's value. If you want to make sure that a global is initialized to a particular value, add the initializer to the definition like int globalvariable = 42;.
The problem with this is that you may get linking errors due to multiple definitions when you try to link your program. You're depending on implementation defined behavior here -- the implementation is allowed to treat the duplicate definitions as all referring to a single object, but is not required to.
extern int globalvariable;
is a declaration
int globalvariable;
is both a declaration and a tentative definition.
In C, it's illegal for the same variable to have multiple definitions, and that will happen if you use the latter in a header file that's included in more than one translation unit.
Unix systems however historically allow this usage, so most compilers will accept the code despite it being invalid C.
The drawback of your code is that you will probably get a linker error.1
1. Where "probably" is based on the notion of building your code on a whole bunch of different toolchains.
ANSI C standard says
If the declaration of an identifier for an object has file scope and
no storage-class specifier, its linkage is external.

How do I share variables between different .c files? [duplicate]

This question already has answers here:
How do I use extern to share variables between source files?
(19 answers)
Closed 6 years ago.
beginner question about C declaration:
In a .c file, how to use variables defined in another .c file?
In fileA.c:
int myGlobal = 0;
In fileA.h
extern int myGlobal;
In fileB.c:
#include "fileA.h"
myGlobal = 1;
So this is how it works:
the variable lives in fileA.c
fileA.h tells the world that it exists, and what its type is (int)
fileB.c includes fileA.h so that the compiler knows about myGlobal before fileB.c tries to use it.
if the variable is :
int foo;
in the 2nd C file you declare:
extern int foo;
In 99.9% of all cases it is bad program design to share non-constant, global variables between files. There are very few cases when you actually need to do this: they are so rare that I cannot come up with any valid cases. Declarations of hardware registers perhaps.
In most of the cases, you should either use (possibly inlined) setter/getter functions ("public"), static variables at file scope ("private"), or incomplete type implementations ("private") instead.
In those few rare cases when you need to share a variable between files, do like this:
// file.h
extern int my_var;
// file.c
#include "file.h"
int my_var = something;
// main.c
#include "file.h"
use(my_var);
Never put any form of variable definition in a h-file.
Try to avoid globals. If you must use a global, see the other answers.
Pass it as an argument to a function.
Those other variables would have to be declared public (use extern, public is for C++), and you would have to include that .c file. However, I recommend creating appropriate .h files to define all of your variables.
For example, for hello.c, you would have a hello.h, and hello.h would store your variable definitions. Then another .c file, such as world.c would have this piece of code at the top:
#include "hello.h"
That will allow world.c to use variables that are defined in hello.h
It's slightly more complicated than that though. You may use < > to include library files found on your OS's path. As a beginner I would stick all of your files in the same folder and use the " " syntax.
The 2nd file needs to know about the existance of your variable. To do this you declare the variable again but use the keyword extern in front of it. This tells the compiler that the variable is available but declared somewhere else, thus prevent instanciating it (again, which would cause clashes when linking). While you can put the extern declaration in the C file itself it's common style to have an accompanying header (i.e. .h) file for each .c file that provides functions or variables to others which hold the extern declaration. This way you avoid copying the extern declaration, especially if it's used in multiple other files. The same applies for functions, though you don't need the keyword extern for them.
That way you would have at least three files: the source file that declares the variable, it's acompanying header that does the extern declaration and the second source file that #includes the header to gain access to the exported variable (or any other symbol exported in the header). Of course you need all source files (or the appropriate object files) when trying to link something like that, as the linker needs to resolve the symbol which is only possible if it actually exists in the files linked.

How to correctly use the extern keyword in C

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.

Resources