0
votes

[the Environment is QTCreator 4.2.1, the compiler is MinGW 5.8]

I've created a header "header.h" with the following code :

#ifndef HEADER_H
#define HEADER_H

int variable = 0;

#endif // HEADER_H

And I tried to include the header in two .cpp files, getting multiple definition errors.

But than I changed the code like this and mentioned the static variable (int Class::variable;) in one of two .cpp files:

#ifndef HEADER_H
#define HEADER_H

class Class{
public:
    static int variable;
};

#endif // HEADER_H

Errors disappeared. But why can't I include a header twice without errors and use the global variable inside of two .cpp files (And use it directly, not as a static class member)?

1

1 Answers

1
votes

There are three main reasons that get combined to explain this:

  1. They are two completely different "things". The syntax may look quite the same, but they do two completely different things in C++.
  2. The One Definition Rule
  3. #includeing a header file is logically equivalent, and is exactly equivalent to physically inserting the contents of the header file into whatever #included it.

So, in the first case, with a header file containing int variable = 0;, every translation unit that #includes this file becomes exactly as if

int variable = 0;

Appeared verbatim in every .cpp file that #included it. Exactly the same. And, obviously, that's a One Definition Rule violation (if more than one .cpp has this, and they are linked together). This actually creates an int variable. It defines it. An object called variable pops into existence, out of thin air. Every .cpp file that includes this becomes a proud owner of an int variable. It exists in every .cpp file, and this violates the One Definition Rule.

On the other hand, you have a class declaration, here:

class Class{
public:
    static int variable;
};

This does not define anything. It just declares a Class, that has a static class member. That's it. It does not define any object. It does not pop anything into existence, or materialize anything out of thin air. This just declares a class, and what's inside it. The One Definition Rule does not come into play for the elementary reason that nothing gets defined here.

So, despite very similar syntax, the end result of very similar looking code is quite different, in C++.