简体   繁体   中英

Benefits of using extern declaration in same file as definition?

I'm reading the source of a C project and am trying to discern why a particular use of extern is being used. (Note: This question is related but for C++, not C.) Say I have four header files that each declare an extern const struct:

extern const struct puppy fido;

This struct is defined in a source file like so:

extern const struct puppy fido;
static const struct puppy *puppies[] = { &fido };
const struct puppy fido = { "fido", 10, 10 };

Is there some kind of benefit to marking the variable declaration as extern in the source file, when those variables are defined in that very same source file?

The only advantage would be that any code between the declaration and the definition will be able to access the variable. Apart from that, the extern declaration in the same file is pointless.

Lundin is correct, that in this case extern does not affect visibility of fido in other source files. In your example code, it is used as a forward declaration.

Relevant part from C99 standard, section 6.2.2:

4) For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible, if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage.

5) If the declaration of an identifier for a function has no storage-class specifier, its linkage is determined exactly as if it were declared with the storage-class specifier extern. If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external

In C++, behavior would be different, because variables declared with const are implicitly static . In C++, you are required to declare the variable with extern the first time, or other compilation units would not find it.

C++98 standard, section 3.5.3:

A name having namespace scope (3.3.5) has internal linkage if it is the name of

— an object, reference, function or function template that is explicitly declared static or,

— an object or reference that is explicitly declared const and neither explicitly declared extern nor previously declared to have external linkage;

Sometimes, when you write a source file, you just want a piece of a header file, not the whole thing.

Repeating the extern declaration in the source file allows you not to include the header file in that specific source file.

This is not necessarily a good practice.

extern const struct puppy fido;
// ...
const struct puppy fido = { "fido", 10, 10 };

If const struct puppy fido = { "fido", 10, 10 }; is compiled in 2 different .c files, it will fail. There should be #ifndef and endif before and after the const struct puppy fido = { "fido", 10, 10 }; in order to include it once.

A good practice (globals variables have to be avoided in general) is to declare with extern in the .h files, and to put the definition of the variable in a .c file.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM