What is meant by the "scope" of a variable? think of the scope of a variable as "The scope of a particular variable is the range within a program's source code in which that variable is recognized by the compiler".
That definition matches the definition of scope in the C# specification; it says:
The scope of a name is the region of program text within which it is possible to refer to the entity declared by the name without qualification of the name
Notice that the C# specification calls out that it is the name which has a scope. Some variables do not have names, and therefore have no scope. And some things have names but are not variables; class names, namespace names, function names, and so on, all have a scope.
The scope of a local variable is frequently confused with its lifetime. The lifetime of a local variable is sometimes related to its scope; when control leaves the scope of a local (either through normal means or via an exception) then the local can be destroyed without anyone noticing. However, the runtime is permitted to make the lifetime of a local variable shorter if it can do so without anyone noticing. The runtime is also permitted to make a local variable live longer than its scope. And there are some situations in which a local variable is required to live beyond when control leaves its scope. (For instance, when the local is a closed-over outer variable of a lambda.)
Therefore it is unwise to use "scope" as a synonym for "lifetime". They are often related but can be quite different. Use "scope" to mean "the region of text in which a name is valid", not "the period of time in which a variable is alive". Scope is fundamentally a compile-time concept.
What exactly is the difference between the scope of variables in C# and (C99, C++, Java)
I am not sufficiently familiar with the exact scoping rules of C, C++ or Java to give a short list of the differences. I can however point out some oddities of C#.
The first is that in C#, a local variable is in scope throughout its block.
class C
{
int x;
void M()
{
int y = x;
int x = y;
}
}
In C++, the first "x" means "this.x" because the local variable x is not in scope until its declaration. In C#, the local variable x is in scope throughout the block. Using a local that is in scope before its declaration is an error in C#.
The second is that in C#, a simple name must mean the same thing throughout the scope in which it is first used:
class C
{
int x;
void M()
{ // M starts
int y = x;
if (y > 100)
{
int x = y;
}
}
}
This is illegal because inside the block labelled "M starts" the simple name "x" is used to mean two different things. Now the first "x" means "this.x" because the local is not in scope. But it is illegal to use the same name to mean two different things, because that is a source of bugs.
If this subject interests you, I have written a number of articles on it. See
http://blogs.msdn.com/b/ericlippert/archive/tags/scope/
http://blogs.msdn.com/b/ericlippert/archive/tags/declaration+spaces/
UPDATE: The rule that a simple name must have a unique meaning throughout the block which encloses it has been relaxed in C# 6. The language design team decided that the cost of user confusion was too high for the benefit in catching bugs.
Each computer language has its strengths and pitfalls. Each has its own coding standards/practices often accepted, built and dictated by the community around it. Because programming is a precise art I would say, unless there is a good reason to do something, you shouldn't.
Now there are very good reasons to declare variables close to where they are used:
- Makes it easy to determine the type, when reading code.
- Makes it easy to delete code including the declaration all together.
But as you suggest, for some languages there are better reasons to not do that, for sake of clarity or scope. Another reason could be to reserve memory or registers early on, again it depends on the language you are using. A new language may come along with non-C like semantics and may require a different approach to where variables get declared.
I would also always recommend following the coding standards established by the community for your language of choice.
Best Answer
Scope, visibility and accessibility are all really talking about the same thing; given a particular declaration when can that declaration be referenced. Scope is the most general term and encompasses both visibility and accessibility and the referenced quote is adequate. Visibility and accessibility are usually applied to the members of a class as it is easier to think of them as being "hidden" or "not visible" as opposed to out of scope; that is,
myMember
is eitherprivate
,protected
orpublic
controlling the visibility of the member in a class and its decedents. When inside a method of a class, all members are accessible or visible but onlypublic
members are from outside the class.protected
members are only accessible or visible from the class itself or one of its derived classes. All of these contribute to the scope ofmyMember
, that is the smallest region of text that can accessmyMember
.The parenthetical about lifetime is technically accurate for local variables but is really mixing a runtime concept, lifetime, with a compile-time or lexical concept, scope. You should ignore it. It is more confusing than helpful when trying to understand scope. Understanding lifetime is important to understand when a destructor is run and is related to scope but not important in understanding scope.