Midnight Blue
Midnight Blue

Reputation: 5141

What's the difference between using extern and #including header files?

I am beginning to question the usefulness of "extern" keyword which is used to access variables/functions in other modules(in other files). Aren't we doing the same thing when we are using #include preprocessor to import a header file with variables/functions prototypes or function/variables definitions?

Upvotes: 32

Views: 12881

Answers (4)

Zine.Chant
Zine.Chant

Reputation: 63

There are indeed two ways of using functions/variables across translation units (a translation unit is usually a *.c/*.cc file).

One is the forward declaration:

  • Declare functions/variables using extern in the calling file. extern is actually optional for functions (functions are automatically extern), but not for variables.
  • Implement the function/variables in the implementing file.

The other is using header files:

  • Declare functions/variables using extern in a header file (*.h/*.hh). Still, extern is optional for functions, but not for variables. So you don't normally see extern before functions in header files.
  • In the calling *.c/*.cc file, #include the header, and call the function/variable as needed.
  • In the implementing *.c/*.cc file, #include the header, and implement the function/variable.

Google C++ style guide has some good discussions on the pros and cons of the two approaches.

Personally, I would prefer the header file approach, as it is the single place (the header file) a function signature is defined, calling and implementation all adhere to this one piece of definition. Thus, there would be no unnecessary discrepancies that might occur in the forward declaration approach.

Upvotes: 2

64BitLich
64BitLich

Reputation: 21

The #include preprocessor directive simply copy/pastes the text of the included file into the current position in the current file.

extern marks that a variable or function exists externally to this source file. This is done by the originator ("I am making this data available externally"), and by the recipient ("I am marking that there is external data I need"). A recipient with an unsatisfied extern will cause an Undefined Symbol error.

Which to use? I prefer using #include with the include guard pattern:

#ifndef HEADER_NAME_H
#define HEADER_NAME_H
<write your header code here>
#endif

This pattern allows you to cleanly separate anything you want an outsider to have access to into the header, without worrying about a double-include error. Any time I have to open a .c file to find what externs are available, the lack of a clear interface makes my soul gem crack.

Upvotes: 2

Michael
Michael

Reputation: 55425

extern is needed because it declares that the symbol exists and is of a certain type, and does not allocate storage for it.

If you do:

int foo;

In a header file that is shared between several source files, you will get a linker error because each source would have its own copy of foo created and the linker will be unable to resolve the symbol.

Instead, if you have:

extern int foo;

In the header, it would declare a symbol that is defined elsewhere in each source file.

One (and only one) source file would contain

int foo;

which creates a single instance of foo for the linker to resolve.

Upvotes: 27

jcopenha
jcopenha

Reputation: 3975

No. The #include is a preprocessor command that says "put all of the text from this other file right here". So, all of the functions and variables in the included file are defined in the current file.

Upvotes: 3

Related Questions