2.3 Scope

The scope of an identifier is the range of the program in which the declared identifier has meaning. An identifier has meaning if it is recognized by the compiler. Scope is determined by the location of the identifier's declaration. Trying to access an identifier outside of its scope results in an error. Every declaration has one of four kinds of scope:

An enumeration constant's scope begins at the defining enumerator in an enumerator list. The scope of a statement label includes the entire function body. The scope of any other type of identifier begins at the identifier itself in the identifier's declaration. See the following sections for information on when an identifier's scope ends.

2.3.1 File Scope

An identifier whose declaration is located outside any block or function parameter list has file scope. An identifier with file scope is visible from the declaration of the identifier to the end of the compilation unit, unless hidden by an inner block declaration. In the following example, the identifier off has file scope:

int off = 5;     /*  Declares (and defines) the integer
                        identifier off.                           */
main ()
{
   int on;       /*  Declares the integer identifier on.          */
   on = off + 1; /*  Uses off, declared outside the function
                     block of main.  This point of the
                     program is still within the
                     active scope of off.                         */
   if (on<=100)
   {
     int off = 0;/*  This declaration of off creates a new object
                     that hides the former object of the same name.
                     The scope of the new off lasts through the
                     end of the if block.                         */
     off = off + on;
     return off;
   }
}

2.3.2 Block Scope

An identifier appearing within a block or in a parameter list of a function definition has block scope and is visible within the block, unless hidden by an inner block declaration.

Block scope begins at the identifier declaration and ends at the closing brace (}) completing the block. In the following example, the identifier red has block scope and blue has file scope:

int blue = 5;                /*  blue: file scope            */
main ()
{
    int x = 0 , y = 0;       /*  x and y: block scope        */
    int red = 10;            /*  red: block scope            */
    x = red + blue;
}

2.3.3 Function Scope

Only statement labels have function scope (see Chapter 7). An identifier with function scope is unique throughout the function in which it is declared. Labeled statements are used as targets for goto statements and are implicitly declared by their syntax, which is the label followed by a colon (:) and a statement. For example:

int func1(int x, int y, int z)
{
  label:  x += (y + z);   /*  label has function scope        */
  if (x > 1) goto label;
}
int func2(int a, int b, int c)
{
  if (a > 1) goto label; /*  illegal jump to undefined label */
}

See Section 7.1 for more information on statement labels.

2.3.4 Function Prototype Scope

An identifier that appears within a function prototype's list of parameter declarations has function prototype scope. The scope of such an identifier begins at the identifier's declaration and terminates at the end of the function prototype declaration list. For example:

int students ( int david, int susan, int mary, int john );

In this example, the identifiers (david, susan, mary , and john ) have scope beginning at their declarations and ending at the closing parenthesis. The type of the function students is "function returning int with four int parameters." In effect, these identifiers are merely placeholders for the actual parameter names to be used after the function is defined.


Previous Page | Next Page | Table of Contents | Index