20.2.1.  Default Scope of Identifiers - More Detail

[ fromfile: scopestorage.xml id: defaultscope ]

  1. Block Scope. 

    • An identifier declared inside curly braces { ... } (excluding namespace blocks) or in a function parameter list has block scope.

    • Block scope extends from the declaration to the enclosing right brace.

  2. Function Scope. 

    • A label is an identifier followed by a colon (:).

    • Labels in C/C++ functions have their own scope.

    • They are accessible before and after their declaration, throughout the function definition.

    • C and C++ support a very rarely used and (justifiably) shunned goto statement that requires a label.

    Example 20.3. src/goto/goto.cpp

    [ . . . . ]
    int look() {
        int i=0;
        for (i=0; i<10; ++i) {
            if (i == rand() % 20)
                goto found; 1
        }
        return -1;
    found:                  2
        return i;
    }
    [ . . . . ]
    

    1

    It would be better to use break or continue.

    2

    goto serves as a forward declaration for a label.


    • A related but less dangerous use of labels is in the switch statement block.

    Example 20.4. src/switch/switchdemo.cpp

    #include <QTextStream>
    #include "usermanager.h"
    
    QTextStream cout(stdout);
    QTextStream cin(stdin);
    enum  Choices {LOAD = 1, ADD, CHANGE, CHECK, SAVE, LIST, QUIT}; 1
    
    // Function Prototypes
    void addUsers(UserManager&);
    void changePassword(UserManager&);
    Choices menu();
    
    //etc.
    
    int main() {
      // some code omitted
      while (1) {
        switch (menu()) {                                           2
        case LOAD:  
          cout << "Reading from file ...\n"
    	   << um.loadList() << " loaded to list"
    	   << endl;
          break;
        case ADD:
          cout << "Adding users to the list ..." << endl;
          addUsers(um);
          break;
        case SAVE:
          cout << "Saving changes ...\n"
    	   << um.saveList() << " users in file" << endl;
          break;
        case CHANGE:
          cout << "Changing password ..." << endl;
          changePassword(um);
          break;
        case CHECK:
          cout << "Checking a userid/pw combo ..." << endl;
          checkUser(um);
          break;
        case LIST:
          cout << "Listing users and passwords ...\n";
          um.listUsers();
          break;
        case QUIT:
          cout << "Exiting the program ..." << endl;
          return 0;
        default:
          cout << "Invalid choice! " << endl;
        }
      }
    }
    

    1

    enums are discussed in Chapter 19.

    2

    menu() obtains a value from the user.


        [Note]Note

        Even though goto is part of the C++ language, you should not use it.

      • Namespace Scope. 

        • An identifier declared inside a namespace has namespace scope.

        • It can be used anywhere, below the declaration, inside the namespace definition.

        • namespace definitions are open and can be expanded.

        Example 20.5. src/namespace/openspace/opendemo.txt

        //File:  a.h"
        #ifndef _A_H_
        #define _A_H_
        
        #include <iostream>
        namespace A {
          using namespace std;
          void f() { cout << "f from A\n"; }
          void g() { cout << "g from A\n"; }
        }
        #endif
        
        //File:  new-a.h
        #ifndef NEW_A_H_
        #define NEW_A_H_
        #include <iostream>
        
        namespace A {
          //void k() { h(); }                      1
          //void g() { cout << "Redefine g()/n"; } 2
          void h() { 
            cout << "h from newA\n";
            g();
          }
        }
        #endif
        
        File: opendemo.cpp
        #include "a.h"
        #include "new-a.h"
        
        int main() {
          using namespace A;
          f();
          h();
        }
        
        /*Run
        
        openspace> ./a.out
        f from A
        h from newA
        g from A
        openspace>
        
        */
        

        1

        Error!

        2

        Error!


      • Class Scope. 

        • Class Scope is anywhere in the class definition [80] or in the bodies of member functions. [81]

      • File Scope. 

        • An identifier whose declaration is not between curly braces can have file scope if it is declared static.

        • Its scope extends from the declaration to the end of the file.

        • File Scope variables cannot be declared extern and accessed from another file.

          [Note]Note

          File scope is available in C++ for backward compatibility with C, but namespaces or static class members should be used instead whenever possible.

        • Global Scope. 

          • Non-static identifier declaration not contained in any function body.

          • Scope is from the declaration to the bottom of the file but can extend to other source files.

          • The extern declaration may be used to access a globally defined identifier in other source files.

          • Because a compiler deals with one source file at a time, only the linker (or a template-compiler) makes a strong distinction between global and file scope, as Example 20.6 shows.

          Example 20.6.  Global Versus File Scope

          In file 1:

          int g1;        // global
          int g2;        // global
          static int g3; // keyword static limits g3 to file scope
          (etc.)

          In file 2:

          int g1;           // linker error!
          extern int g2;    // OK, share variable space
          static int g3;    // okay, 2 different variable spaces
          (etc.)

          • An identifier in a namespace can be made available globally through the use of the scope resolution operator, NamespaceName::.

          • It can also be made available to other scopes without using scope resolution through the using keyword.

          • Namespace variables and static class members have static storage and can be made accessible globally.

          • They are like global variables, except that they do not enlarge (pollute) the global namespace.

          • See Section 20.4 for more details.



        [80] Including inline function definitions above the declaration of referred members.

        [81] Keeping in mind that the scope of non-static members excludes the bodies of static member functions.