7

I am wondering if it is possible to both declare and define an extern variable in the same header file. I need the variable to be referenced across multiple files, and while I realize there are better ways to achieve this, using extern is the only option in this case. So is it possible to do:

// in main.h
extern int foo;
int foo;

etc...

And then any file which includes main.h will have access to foo? Many examples reference defining the extern'd variable in a separate cpp file, but I'm just wondering if the way I suggested will cause problems across the rest of the project.

4
  • 4
    Read up on the one definition rule. You are asking if you can violate it. Commented Aug 10, 2015 at 17:18
  • 1
    It's possible, but not a good idea. There's supposed to be only one actual definition, shared by everything that needs it, that everything else will link to -- if you define it in the header, you get multiple definitions (one in each translation unit that includes the header), which defeats the purpose of using extern. If you only use the header once it'll work, though. Commented Aug 10, 2015 at 17:20
  • See, amongst other SO questions, How do I use extern to share variables between source files in C? Commented Aug 10, 2015 at 17:27
  • it is (almost) always a bad idea to declare ANY variable, struct instance, union instance in a header file, because there will be another instance of such variable for each and every file the header is included in. Strongly suggest: declare the variable instance in some source file and only have the 'extern' statement in the header file. Commented Aug 10, 2015 at 17:59

3 Answers 3

15

If you put a definition in a header file, you will end up with multiple definitions when multiple source files are involved.

For example, suppose both main.c and other.c include foo.h. When you compile each of these files you'll get main.o and other.o, both of which have a definition of int foo. If you then attempt to link main.o and other.o into a single executable, you'll get a linker error stating that int foo was defined twice.

To do this properly, you declare your variable in the header file as extern int foo. Then, in one (and only one) source file you define the variable with int foo.

Sign up to request clarification or add additional context in comments.

3 Comments

So in the current project, I have a mix of C and cpp files. The C files include foo.h which includes the main.h I reference above. The cpp files do the same, except foo.h is included in an extern "C" block. When I add my own cpp file to this project, including foo.h in the extern C block, the linker then throws LNK2005 errors. Any reason why my addition would be causing these linker errors?
@Jesavino does this answer the question you posted?
Yes, it does. I'm still hoping for the follow up answer, but I accepted it.
4

Real definitions (not extern) should not be in a header file.

If you want to have one global variable available from different cpp, you should make two things: definition in one cpp and extern declaration in h.

E.g.:

// global.h
extern int foo;

and

// global.cpp
int foo;

Then in any file where foo is needed:

#include "global.h"

And, of course, global.cpp have to be part of project (compiled with other files)

Comments

1

What you are doing is perfectly legal in C++ only if there aren't multiple files which are defining the same variable.

The variable or function may be defined in another source file, or later in the same file. Declarations of variables and functions at file scope are external by default.

Normally we extern a global variable declared in some other file.

This is as good as a global variable initialized to 0.

2 Comments

There may not be multiple files defining the variable, but there may be multiple translation units defining it (via the same header file). It's legal to put the definition in a header file (though not generally a good idea), but you can still end up with extra definitions from different translation units that use that header.
If the definition is put inside an #ifdef block, wouldn't that prevent multiple definitions even when the header is included in multiple places?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.