2

In file1.cc I write

int i = 0;

while in file2.cc I write

#include <iostream>

int i = 1;

int main()
{
  std::cout<< i << std::endl;
  return 0;
}

In MacOS the compiler reports

duplicate symbol _i in:
/var/folders/wn/q9648wb507j9l504vp2d_dwm0000gn/T/file1-bb8eca.o
/var/folders/wn/q9648wb507j9l504vp2d_dwm0000gn/T/file2-b5e667.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

But isn't it that different files have their different scopes, so that we can define a global variable in file2 with the same name as in file1? Moreover, if different files are in the same scope, then why is it illegal to transform file2.cc as:

#include <iostream>

int main()
{
  std::cout<< i <<std::endl;
  return 0;
}
Felix
  • 209
  • 1
  • 3
  • 8
  • 5
    If you want your global variables to have internal linkage (i.e. to be visible only within a file they are defined in) - mark them as `static`, or put them in anonymous `namespace`. – Algirdas Preidžius Dec 23 '16 at 13:45
  • you should have "extern i" in file2.cc – aram Dec 23 '16 at 13:46
  • A global variable is **global** -- it's available everywhere. – Pete Becker Dec 23 '16 at 14:04
  • 1
    Note that files and language rules concerning scope, visibility or lifetime are orthogonal. What you are really asking is whether variables in different *translation units* have different scopes. A translation unit is usually composed from many different files - the *.cc or *.cpp (or whatever) file and the header files pulled in directly or indirectly with `#include`. See http://stackoverflow.com/questions/1106149/what-is-a-translation-unit-in-c – Christian Hackl Dec 23 '16 at 15:01

3 Answers3

6

Multiple definitions of same global variable are not allowed. You must mark your variables static, const, or place them in an anonymous namespace. Else they are in the global scope.

And your second question: The example code does not compile, because the compiler does not see the global variable from the other file, because a compiler compiles one translation unit (C++ file) at a time. This is why you need to add extern i;. This tells the compiler, that the variable will be defined in another translation unit.

After all files have been compiled successfully, they will be linked. Linker checks all translation units. When you get an error about multiple definitions, this error occurs during linking.

VLL
  • 9,634
  • 1
  • 29
  • 54
  • 1
    The unnamed namespace rule is only valid from c++11, right? http://stackoverflow.com/questions/13396748/are-objects-in-anonymous-namespace-implicitly-static – simon Dec 23 '16 at 13:54
  • Thanks! Your answer perfectly erases my confusion :) – Felix Dec 23 '16 at 14:01
1

The global scope for files linked in the same executable is the same. To avoid that you could declared it static, but that is deprecated in c++.
The correct way to separate the scope of the two files is to use namespaces.

Nogoseke
  • 969
  • 1
  • 12
  • 24
1

Your variable is in the same scope. You have to use namespaces in order to declare to variables with the same name.

Darth Coder
  • 312
  • 2
  • 11