Programe #1

inside file.h

class File
{
public:
    static const int var = 9;
};

inside main.cpp

#include <iostream>
#include "file.h"
using namespace std;

int main() {
    File f;
    cout << f.var;
    return 0;
}

Programe #2

inside file.h

int Globalvar ;
class File
{
public:
    static const int var = 9;
};

inside main.cpp

extern int GlobalVar;

#include <iostream>
#include "file.h"
using namespace std;

int main() {
    cout << GlobalVar;
    return 0 ;
}

Program#1 is running fine, but program#2 gives linker error:

error LNK2005: "int GlobalVar" (?x@@3HA) already defined in file.obj
I know the header files are never compiled. Then in the above case, how the compiler knows the definition of variable var, but not able to find the definition of GlobalVar? What is the difference between this two programs?

Recommended Answers

All 4 Replies

I know the header files are never compiled.

Header files are always compiled if you include them. The problem is that you have an object definition in a header file, which means that by including it more than once you've violated the one definition rule. Inside the header you should be using the extern keyword:

// file.h
#ifndef FILE_H
#define FILE_H

extern int GlobalVar; // Declaration only

class File
{
public:
    static const int var = 9;
};

#endif

Then ideally you would have an implementation file for the header that handles the one definition:

// file.cpp
#include "file.h"

int GlobalVar = 0; // Definition

Compile and link file.cpp as normal, include file.h wherever you want, and all will be well using this design.

I got what you are saying .
But why it is not happening with program#1 i.e for static . There also it should display one linker error since we have defined static variable inside .h file .Please correct me if i am wrong .

There also it should display one linker error since we have defined static variable inside .h file

Different things, different mechanics. You would get a redefinition error concerning the class if you included file.h twice either directly or indirectly, but that has more to do with the class than the static const member. Note that my example file.h has inclusion guards to protect against that particular problem by only including the header one time per translation unit.

There also it should display one linker error since we have defined static variable inside .h file.

No. There is a certain allowance for static const data members which is similar to the allowance for inline functions (functions defined in the header file either within a class declaration or marked as inline). For static const data members of primitive types (e.g., integers), it is allowed to define them in the header file even if that would technically lead to One Definition Rule (ODR) violations, because for such primitive types and under the assumption that all instances of those data members seen by the linker came from the same header file, it is safe to assume that they will all be equal. And because they are constant, there is no problem in having many copies (or optimizing them away entirely), but if non-const, then there must be a guarantee of a single instance being manipulated. And because they are of primitive types (with trivial constructors), there are no issues of side-effects from the multiple construction of the static data member (in multiple translation units), but if non-primitive, then there must be a guarantee that the construction happens only once during the static initialization. So, obviously, this exceptional rule doesn't apply to static data members that are non-const and/or non-primitive (class type), in which case, they must be defined in one translation unit only (one compiled cpp file).

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.