Reputation: 1577
I am playing around with multiple files in C++, and I have come of with the following example with does not compile:
main.cpp
#include <iostream>
#include "const.hpp"
using namespace std;
int main()
{
extern double var;
var = 5;
cout << var << endl;
return 0;
}
fct.cpp
#include <iostream>
#include "const.hpp"
using namespace std;
void func()
{
extern double var;
cout << var << endl;
}
const.hpp
#ifndef CONST_H
#define CONST_H
double var;
#endif
My program does not compile, because apparently there is a multi-definition of var. Am I correct to assume that, based on this example, a header file is not intended to be used for declaring variables as in my example above?
Instead, the correct procedure is to declare all variables in a .cpp file and use a header to tell each (relevant) translation unit that the .cpp file contains an external (extern) variable?
EDIT: Is it correct that an exeption to my rule above is when dealing with constant variables (const), which should be defined in a header?
Upvotes: 2
Views: 450
Reputation: 126412
Am I correct to assume that, based on this example, a header file is not intended to be used for declaring variables as in my example above?
A header file is intended for declaring variables, but your header file defines a global variable with external linkage, and it is imported multiple times. The linker then reasonably complains about multiply defined symbols.
Instead, the correct procedure is to declare all variables in a .cpp file and use a header to tell each (relevant) translation unit that the .cpp file contains an external (extern) variable?
Yes, except that you would not be declaring the global variables in that .cpp
file, but rather providing a definition for them.
const.hpp
#ifndef CONST_H
#define CONST_H
// ...
extern double var;
// ^^^^^^
#endif
globals.cpp
(could be any other .cpp
file, as long as it is only one)
// ...
double var;
Also, if you are wondering about the reason why your include guards won't protect you in this case, this may help you .
Is it correct that an exception to my rule above is when dealing with constant variables (const), which should be defined in a header?
In a sense, yes. Global variables qualified as const
have internal linkage by default, which means that each translation unit will receive a private copy of that variable. So even when the variable's definition is included by multiple translation unit, the linker will not complain about multiply defined symbols.
Upvotes: 3
Reputation: 258548
double var;
is a definition - including that header in multiple files will violate the one definition rule. If you want a global (think twice) you'll have to declare it in the header - extern double var;
and move the definition to a single implementation file.
Upvotes: 4