Click here to Skip to main content
15,881,882 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi! I'm a C++ beginner and a new guy of CodeProject. Because English is not my native language, maybe my expression is not very good. Here is the code that puzzles me:

C++
#include <iostream>
using namespace std;

int x = 5;

int func()
{
	int x = 4;
	{
		extern int x;
		return x;
	}
}

int main()
{
	cout<<func()<<endl;
}


Compiled by gcc , it prints a "5" when I run it. If I throw the "extern int x; " away it prints a "4". And if I write:

C++
int func()
{
	int x = 4;
	extern int x;
	return x;
}


Then the program occurs an error.

So the question is: 1 Why the external "x" is referenced ? 2 Why I can't throw away the braces that encloses the extern declaration? Please give me a few hints.
Posted

Have a look at this: What is the use of extern in C?[^]. I think it answers both questions quite nicely.
 
Share this answer
 
You've mixed two base concepts here: visibility and extern declarations.

Visibility refers to the resolution of variable names: when there are multiple declarations of the same name, the compiler will use the one of the innermost scope. In your first example that is the line extern int x; In your second example the two declarations are in the same scope, but in this case the later one hides the former ones. this causes the error

Note that it does not matter whether this declaration contains extern with respect to visibility rules: in any case this declaration effectively hides the declaration above: int x = 4;

extern tells the compiler that you are referring to a variable declared elsewhere in (or possibly outside) your codebase. That may be within the same, or a different compilation unit. In any case, that variable declaration must be in the global namespace, so a local definition within your function func() will not be usable as an extern. therefore there is only one variable declaration usable as an extern in your first code example, and that is the first one. The second example contains no global definition for x however. therefore the system* cannot resolve what your declaration extern int x; refers to, and that causes the error.

(*: I would expect the linker to issue an error here; not sure why you said the program does - or did you mean the linker?)

[edit]fixed[/edit]
 
Share this answer
 
v2
Comments
Orjan Westin 9-Jan-12 5:08am    
The second example, I take it, only shows the modified func() with the rest being equal. So it's not a case of the linker not being able to resolve x, but two x in the same scope.
Stefan_Lang 9-Jan-12 5:51am    
Thanks. Of course you're right. Fixed it.
The reason you can't do away with the curly braces is to do with scope. A named variable refers to one previously declared in the same scope, or closest outer scope. You can have variables with the same name in different scopes (they don't even have to be the same type), in which case the one currently visible (eg declared in the same or closest outer scope) hides the others.

Put simply, the extern keyword in this case tells the compiler to use the "x" declared in the global scope, not the one closest.
C++
int x = 5; // Global scope

int func()
{
  // At this point, "x" refers to the global, with value 5
  int x = 4;
  // A local "x" has been declared in this scope, so it hides the global
  {
    // New scope, closest declaration (x=4) is still the visible one
    extern int x; // Now "x" refers to the global
    return x;
  }
}


If you throw away the braces, you have two "x" in the same scope - both the local and the global - and that is an error.
 
Share this answer
 
v2
Comments
Bo Ye 9-Jan-12 8:19am    
Thanks. I am enlightened with your comments.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900