views:

530

answers:

5

Say I have a class definition:

class CustomClass {
    int member;
};

Why is the following variable definition compiling and working correctly:

CustomClass CustomClass; // the variable is properly constructed

Should't this confuse the compiler and cause it to indicate an error?

+8  A: 

Class names and variable names occupy two separate namespaces. The compiler is able to figure out that the first CustomClass is a type and the second CustomClass is a variable name.

Don McCaughey
The concept of namespaces as you've described here is the correct terminology in C. In C++, there are rules which specifically allow this without reference to namespaces. It simply comes down to allowing a type and object, or a type and function where the type is hidden by the other declaration.
Richard Corden
Not sure I quite understand what you're saying here, but from the point of view of the compiler in either C or C++, type names are kept in one list, global variable names in another, local variable names in list for each local scope, etc. Each of these lists is a "namespace" internal to the compiler (and distinct from the C++ concept of namespaces).
Don McCaughey
+1  A: 

The requested doubt is not necessarily about the case sensitive mode of C++ , it's the variable declaration that has the same name as the class defined above. I'm thinking that your c++ compiler is smart enough to deduce the type of the token that it's parsing ..

Lucas
A: 

I think its compiler magic thats making it work. I agree with you that this ideally should be a compiler error (atleast confuses me).

If you try something like

#include <iostream>
class Test { public: int member; };
Test Test;   // comaeu warns 'expression has no effect!'
Test.member = 10; // dosen't compile!

int main(){
  Test Test;   
  Test.member = 10; // compiles fine after global 'Test's are commented!!
  std::cout<<Test.member<<std::endl;
  return 0;
}

The use of 'Test.member' at global scope will not compile, but the same works inside 'main()' after both the global 'Test's are commented.

C++ has enough complexities to excite programmers, how about compilers too contributing :-) ?

Abhay
A: 

This answer indirectly states the main reason why it is possible to do this in C++. It comes down to backwards compatibility with C. In C types had a different namespace and so it was possible to declare a type and object, or a type and function with the same name.

In order to be compatible with C, C++ added some special rules to allow an object or a function to hide the declaration of a type.

Richard Corden
A: 

Sure, why not? Now how to define class CustomClass again? Easy: use keyword "class", like this: class ; class CustomClass CustomClassAgain;