Why does extern expression have to be outside .c file (according to linux coding style)
According to the checkpatch.pl script "extern expression must be outside of .c file" (used to check if the patch supports coding style) Note: this works fine without compilation warnings Problem is solved by placing extern declaration in .h file.
a.c
-----
int x;
...
b.c
----
extern int x;
==> checkpatch complains
a.h
-----
extern int x;
a.c
----
int x;
b.c
----
#include "a.h"
==> does not complain
I want to understand why this is better
My suggestion. Ideally, the code is split into files to modulate the code (each file is a module) The interface exported by the module is placed in header files so that other modules (or .c files) can include them. therefore, if any module wants to expose some variables externally, then an extern declaration must be added to the header file corresponding to the module.
Again, having a header file corresponding to each module (.c file) is similar for many header files.
source to share
It would be even better to include ah in the ac file that way the compiler can make sure the declaration and definition match.
a.h
-----
extern int x;
a.c
----
#include "a.h" <<--- add this
int x;
b.c
----
#include "a.h"
The reason for the rule is what you think is using a compiler to check what we are doing. It's much better with tiny details.
If we allow extern declarations all over the place, we have problems if we want to change x
to some other type. How many .c files should we scan to find everything extern int x
? Lot. And if we do that, we will most likely find some bugs extern char x
. Unfortunately,
Just having one declaration in the header file and including it where needed will save us a ton of headaches. In any real project x
it won't be the only element in the header file anyway, so you don't keep the number of files.
source to share
I see two reasons:
- If you are sharing a variable, it is because it is not in your own file, so you want to make it clear that it is being shared by adding
extern
a header to the file - so there is only one [include directory] place to look for declarationsextern
. - This avoids someone making a declaration
extern
and then someone else making a different (as when using different types or attributes) extern expression for the same thing. At least if in the header file [which matters] all files use the same declaration. - If you ever decide to change the type, there are only two places to change. If you were to add a "cc" file that also used the same variable and then decided that it was
int
n't good enough, I needlong
you to change all three places, not two, since you'd if in each of " ac "," bc "and" cc "have a header file.
Having a header file for your module is definitely not a bad idea. But it is of course acceptable, depending on the circumstances, to put extern
in some kind of existing header file.
An alternative, which is often a better choice than using extern, is having getter function
, which fetches your variable for you. Thus, a variable can be static in its own source file [no "namespace pollution", and the type of the variable is also much more specific - the compiler can detect if you try to use it incorrectly.
Edit: I should point out that the Linux coding style is the same as for "good" reasons, but that doesn't mean that code that is not part of the Linux source code cannot violate these rules in different ways. I certainly don't write my own code using Linux formatting - I like it better { }
around single statements, and I (almost) always put {
on a new line according to what belongs to the parenthesis, and }
in the same column again.
source to share
One of the reasons I always put extern declarations in .h is to prevent code duplication, especially if there are or could be more bits of code using your "ac" code and have access to "x". In this case, all files must have an extern declaration.
Another reason is that the extern declaration is part of the module's interface and so I would store it along with any other interface information in a header file.
source to share
Your speculation is correct: for maximum code reuse and consistency, (public) declarations should be placed in header files.
Again, having a header file corresponding to each module (.c file) is like many header files.
Then get used to it. This is a logical concept and good adaptation practice.
You have a reason why extern declarations should be placed in a header file. Thus, they can be easily accessed through different translation units.
Also, it is not necessary that every .c file must have a corresponding .h file. A single .h file can correspond to a decent number of .c files depending on your module's segregation design.
source to share
Again, having a header file corresponding to each module (.c file) is like it has a lot of header files.
As you said, the idea of a header file is simple. They contain a public interface that a module wants to export (make available) to other modules (contained in other .c files). This can include structures and types and function declarations. Now, if a module defines a variable that it wants to make available to other modules, it makes sense to include other public parts in it in the header file. This is why externs end up in the header file. They are just part of what the module wants to make public. Then anyone can enable this public interface by simply including the header file.
Having a .h file on a .c file may seem like a lot, but it might be correct. But keep in mind that a module can implement its code in multiple .c files and choose to export its common public interface to a single .h file. So this is not a very strict one-one thing. The real abstraction is the public interface offered by the module.
source to share