Scope is the area in a program where a variable or function (or any other identifier) is define and recognized. A variable or function declared outside of any function (and outside the function main() ) is said to have file scope, i.e. it is recognized by all functions in the file. This is commonly referred to as a global variable.
Variables or functions (or any identifiers) declared inside a block ( a block is a pair of braces like these {} ) are recognized within that block and within any nested blocks. For example, local variables declared in a function have block scope, i.e. their scope is within the function. The same is true for the parameters of the function which are essentially local variables.
For example, if I declare a variable inside a set of braces and access it outside them , the compiler will throw an error and tell me the variable is not declared in the scope.
//after an if
if (true)
{
int p = 8;
}
p++;// out of scope error
//after a generic block
{
int q = 9;
}
q++;// out of scope error
//after an implied block
if (true)
int R = 10;
R++;// out of scope error
As I said, inner nested blocks do have access to variables declared in their parent block. But what if the nested block declares the variable again. This will not cause a compiler error. What will happen is that the inner block will have its own local variable of the same name as the variable in the parent block. The parent block's variable will be hidden to the inner block and any changes made in the inner block to the variable will not affect the variable in the outer block. The same is true where you declare a global variable and then make a variable of the same name inside a function (or any block). This is a confusing technique to use and therefore should be avoided.
Labels have a special scope behavior. Labels have file scope. That means that you can goto a label that inside another block, even outside the current block. This is true of functions as well. You can junmp to a label in a different function. In general, doi9ng this is very bad style.
There are five storage class specifiers in C++: auto, register, extern, mutable, and static.
Declaring a variable to be register means we are telling the compiler we would like the variable to be stored in one of the computers high-speed registers. This request will not necessarily be fulfilled. We does this for variables which we expect to be modifying frequently and there want to save run time by keeping the variable in a register. The compiler may not be able to fulfill this request, if, for example, there are no free registers.
By default all variables are auto, which means they exist only when they are in scope.
You can also declare a variable to be static. This means the variable exists even when it is out of scope. For example, when a function exists, the local variables go out of scope and if they are of type auto (default) they are deleted. But if they are of type static they continue to exist even though they are currently inaccessible. Next time the the function will be called they will again be accessible and will retain their previous value. This could be useful, for example, if I want my function to keep track of how many times it was called. I would then make a static int counter and increment it at each call. Numeric variables of the static storage type are initialized to zero unless explicitly initialized otherwise by the programmer.
As we have said, when creating a global variable you declare it outside of any function in the file. What if another file wants to use that variable? What you need to do then is to compile the two files together. And in the other file, where the global is not declared, you need to declare it with the the keyword extern.
extern int flag;This tells the compiler to let the linker find this variable in another, external file.
There is one catch, if in the original file where the global was defined it was defined to be static then no external file can access it, not even if it uses the keyword extern. Such a static variable is said to have internal linkage, as opposed to external linkage. The same is true of functions. By default, global variables and functions have external linkage, i.e. they can be accessed by external files.
It is important to note that since the extern declaration file and the actual global variable file are compiled separately, there is nothing to prevent the type in the extern from being different from the actual variable. This usually occurs when someone modifies the actual and is unaware of the extern. The Linker will likely not catch this, depending on the linker and the exact type difference. Bugs like this are difficult to find.
Type mutable is beyond the scope of this course.
© Nachum Danzig October 2011