0

Why do some of these compile and some not compile?

Scenario 1: compilation error 'main' : redefinition; previous definition was 'data variable'

#include <iostream>
using namespace std;
int main;
int main(){ }

Scenario 2: compilation error syntax error : missing ';' before identifier 'obj

#include <iostream>
using namespace std;
class main { };
int main(){ 
   main obj;
} 

Scenario 3: working fine

#include <iostream>
using namespace std;
class main { };
int main(){ 
   class main obj;
} 

Scenario 4 : working fine

#include <iostream>
using namespace std;
class main {};
main obj;
int main(){ }
M.M
  • 138,810
  • 21
  • 208
  • 365
Alok
  • 1,997
  • 2
  • 18
  • 30

1 Answers1

7

Name lookup works in terms of names. The name is looked up, independent of what that name designates.

It's not permitted for the same name to be declared as both a function and a variable, in the same scope.

However, it is permitted for class X to exist even if X is the name of a function or a variable. When you have class X, then the current scope gets X as a name (designating that class). If the same scope has X declared as both a typename and a variable name, then just looking up x finds the variable name.

If a new scope declares X then any use of X in that scope finds the name declared in its scope, this is called shadowing. (Name lookup searches the current scope, then the scope which enclosed that, and so on up to the global scope).

  1. Error, attempts to declare main as both a function and a variable

  2. To process main obj;, the name main is looked up. The current scope is checked first, and it finds the function name main; so it does not check the global scope. We say that the inner scope's name shadows the outer scope's name. So, it is the same error as you would get from void foo(); foo obj;

  3. class main unambiguously says to look up the class name main; that does not find int main() so it falls back to checking the global scope.

  4. nothing new, main obj; makes no difference .

Another interesting example would be:

int x;
class x { };

int main()
{
    x = 1;        // ok
    x y;          // error, `x` means the int
    class x y;    // ok
}
M.M
  • 138,810
  • 21
  • 208
  • 365