BillyJean
BillyJean

Reputation: 1577

Proper use of header in C++

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

Answers (2)

Andy Prowl
Andy Prowl

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

Luchian Grigore
Luchian Grigore

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

Related Questions