title: Multiply defined symbols
body: <p>If I declare a global variable in a header file and include it in two .cpp files, the linker gives an error saying the symbol is multiply defined.
  My question is, why does this happen for only certain types of object (eg. int) and not others (eg. enum)?</p>
  
  <p>The test code I used is given below:</p>
  
  <p>test.h</p>
  
  <pre><code>#ifndef TEST_HEADER
  #define TEST_HEADER
  
  namespace test
  {           
          int i_Test1 = -1;
          int i_Test2 = -1;
  };
  
  #endif // TEST_HEADER
  </code></pre>
  
  <p>class1.h</p>
  
  <pre><code>#ifndef CLASS_1_HEADER
  #define CLASS_1_HEADER
  
  class class1
  {
  public:
          void count();
  };
  
  #endif //CLASS_1_HEADER
  </code></pre>
  
  <p>class1.cpp</p>
  
  <pre><code>#include &lt;iostream&gt;
  #include "class1.h"
  #include "test.h"
  
  void class1::count()
  {
          std::cout &lt;&lt; test::i_Test1 &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p>class2.h</p>
  
  <pre><code>#ifndef CLASS_2_HEADER
  #define CLASS_2_HEADER
  
  class class2
  {
  public:
          void count();
  };
  
  #endif //CLASS_2_HEADER
  </code></pre>
  
  <p>class2.cpp</p>
  
  <pre><code>#include "class2.h"
  #include &lt;iostream&gt;
  #include "test.h"
  
  void class2::count()
  {
          std::cout &lt;&lt; test::i_Test2 &lt;&lt; std::endl;
  }
  </code></pre>
  
  <p>main.cpp</p>
  
  <pre><code>#include "class1.h"
  #include "class2.h"
  
  int main(int argc, char** argv)
  {
          class1 c1;
          class2 c2;
          c1.count();
          c2.count();
          return -1;
  }
  </code></pre>
  
  <p>Building this code with:</p>
  
  <pre><code>g++ main.cpp class1.cpp class2.cpp -o a
  </code></pre>
  
  <p>produces the following output:</p>
  
  <blockquote>
    <p>ld: fatal: symbol <code>test::i_Test1' is
    multiply-defined:
            (file /var/tmp//ccwWLyrM.o type=OBJT; file /var/tmp//ccOemftz.o
    type=OBJT); ld: fatal: symbol
    </code>test::i_Test2' is multiply-defined:
            (file /var/tmp//ccwWLyrM.o type=OBJT; file /var/tmp//ccOemftz.o
    type=OBJT); ld: fatal: File processing
    errors. No output written to a
    collect2: ld returned 1 exit status</p>
  </blockquote>
  
  <p>If I change the test.h file as given below:</p>
  
  <p>test.h (with enum)</p>
  
  <pre><code>#ifndef TEST_HEADER
  #define TEST_HEADER
  
  namespace test
  {
          enum val
          {
                  i_Test1 = 5,
                  i_Test2
          };
          //int i_Test1 = -1;
          //int i_Test2 = -1;
  };
  
  #endif // TEST_HEADER
  </code></pre>
  
  <p>I don't get the "multiply defined" error and the program gives the desired output:</p>
  
  <pre><code>5
  6
  </code></pre>