Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C/C++ Scope in two different .cpp files

Tags:

c++

c

I would like to know why you can not declare a global with the same name in 2 different .cpp files. My understanding is considering scope, that it should only be visible to that particular .cpp file and no where else but it is obviously complaining. The reason I'm doing this is for commonality in code and that's it. any ideas?

Edit for Clarity

a.cpp

int g_x;

b.cpp

int g_x;

like image 246
Questioneer Avatar asked Nov 30 '11 17:11

Questioneer


2 Answers

To make a global variable (or function) only visible to the file it's declared in,

  1. declare it static, or
  2. (the way that is preferred in C++) put the variable in a nameless namespace. It would seem like that would make it inaccessible from outside the namespace, but what it actually does is make it only visible to the file in which it is.

To access a global variable (that is not static or in an anonymous namespace) that is declared in some other file, use extern.

The reason why is the same reason why you can't have a function with the same name in two different files. It confuses the linker because global variables by default have external linkage. static or being in an anonymous namespace gives them internal linkage, which makes them like a "local global variable".

like image 173
Seth Carnegie Avatar answered Sep 30 '22 20:09

Seth Carnegie


The Problem:
Global variables have External linkage, i.e: They are visible throughout the program.
if 2 different files have variable with same symbol name then it breaks the ODR(One Definition Rule).

The One Definition Rule (ODR), as the name suggests, requires that an object with external linkage, a non-inline function, a class, an enumeration or a template shall have exactly one definition in the program.


The Solution:
Your global variables in the files should have Internal Linkage to avoid violation of ODR. There are two ways to achieve this:

Make your global variables in file static Or
Use Anonymous/Unnamed namespace.


Good Read:
Anonymous/Unnamed namespace
Speaking Standardese: the One Definition Rule


For Standerdese Fans:
C++11 3.2 One Definition Rule [basic.def.odr]:

No translation unit shall contain more than one definition of any variable, function, class type, enumeration type or template.

Para 3:

Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required. The definition can appear explicitly in the program, it can be found in the standard or a user-defined library, or (when appropriate) it is implicitly defined (see 12.1, 12.4 and 12.8). An inline function shall be defined in every translation unit in which it is odr-used.

C++11 7.3.1.1 Unnamed namespaces [namespace.unnamed]

1/ An unnamed-namespace-definition behaves as if it were replaced by

inlineoptnamespace unique { /* empty body */ }    
using namespace unique ;      
namespace unique { namespace-body }       

where inline appears if and only if it appears in the unnamed-namespace-definition, all occurrences of unique in a translation unit are replaced by the same identifier, and this identifier differs from all other identifiers in the entire program.94

Note: C++03 deprecated usage of static for declaring objects in namespace scope but this deprecation was removed in C++11.

like image 21
Alok Save Avatar answered Sep 30 '22 18:09

Alok Save