views:

262

answers:

8

I had a C++ interview recently where I was asked, how does the compiler differentiate static data members having the same name in two different classes?

Since all static data variables are stored in the data segment, there has to be a way by which the compiler keeps track of which static data belongs to which class especially when they have the same name.

Edit: I answered name mangling, but he refused saying name mangling is used only among the members of the same class.

+1  A: 

The name of the class qualifies the name of the member: myclass::mymemb. The compiler differentiates them the same way you do, when referring to them from outside the class.

Within the implementation, this is done by name mangling; the compiler santizes the name of the class and the name of the member, and catenates them together into a mess such as __i_7myclass_6mymemb.

The name mangling process (or its necessity) is the reason why we need extern "C" for compatibility with C interfaces, which define non-mangled names.

Potatoswatter
+2  A: 

Well I would assume that through name mangling the name of the class is encoded with the data too. I wouldn't be surprised if it's as simple as prefixing the name:

class one
{
   static int data;
};

class two
{
   static int data;
};

could have the names

one::data
two::data

in the data segment. Those are unique names.

miked
I too said name mangling, but he refused saying name mangling is used to differentiate between members of the same class
San
@San, perhaps you are lucky not to be working there.
Mark Ransom
A: 

static members of a class will have their names mangled such that the class name is part of the 'global' name seen by the linker.

Michael Burr
A: 

It attaches the class name to the data member name. (And then name-mangles the whole thing.)

Jim Buck
+2  A: 

A name is just something that is used by humans to give a meaning to things.

Once that the compiler knows that they are different items (since they are declared in different classes) it won't use the name to distinguish them inside the binary, it will use pointers and pointers don't care about names :)

Then nothing forbids from prepending the name of the data with the enclosing class..

Jack
+9  A: 

The names are mangled with their class name in them. An example with the clang compiler

class A {
  static int i;
};

int A::i = 0;

Output

$ clang++ -cc1 -emit-llvm main1.cpp -o -
; ModuleID = 'main1.cpp'
target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
target triple = "i386-pc-linux-gnu"

@_ZN1A1iE = global i32 0, align 4

Where _ZN1A1iE is

$ c++filt _ZN1A1iE
A::i
Johannes Schaub - litb
+5  A: 

It's implementation-defined, so there's no one way it has to be done.

Name mangling is commonly used though.

Jon Hanna
+2  A: 

All the "name mangling" answer address how the debugger finds the storage for each symbol and how the linker knows the difference, but the compiler knows because these entities occupy different entries in the symbol table.

That's it.

The executable doesn't need to know anything about names at all{*}. Just locations. The compiler knows about names, and that knowledge is coded in the symbol table (however it may be implemented).

{*} Well, in the absence of RTTI, anyway.

dmckee
Static class members, unlike static globals, have external linkage. So the linker has to match them up by name, and with dynamic libraries the loader as well. Only the compiler knows what the mangled names actually mean, but linker and loader also use them.
Ben Voigt
@Ben. Yes. I agree. The same thought came to me after I walked away from my computer for lunch. None-the-less, I stand by the position that knowledge of the difference lies in the symbol table: name mangling is merely a serialization of fundamental distinction that they are different symbols.
dmckee
Right. My comment is more of a clarification than a disagreement.
Ben Voigt
+1 I think it's worth explaining that the scopes containing the variables differ. It's not like they're just different entries freefloating in a void. The compiler puts each into its scope - whether by concatenating the elements thereof or building a tree.
Tony