Previous Table of Contents Next


3.20.3 Special Scoping Rules for Type Names


   Once a type has been defined anywhere within the scope of a module, interface or valuetype, it may not be redefined except within the scope of a nested module, interface or valuetype, or within the scope of a derived interface or valuetype. For example:

   typedef short TempType; // Scope of TempType begins here

   module M {

   typedef string ArgType; // Scope of ArgType begins here

   struct S {

   ::M::ArgType a1; // Nothing introduced here

   M::ArgType a2; // M introduced here

   ::TempType temp; // Nothing introduced here }; // Scope of (introduced) M ends here

   // ... }; // Scope of ArgType ends here

   // Scope of global TempType ends here (at end of file)

   The scope of an introduced type name is from the point of introduction to the end of its enclosing scope.

   However, if a type name is introduced into a scope that is nested in a non-module scope definition, its potential scope extends over all its enclosing scopes out to the enclosing non-module scope. (For types that are defined outside an inon-module scope, the scope and the potential scope are identical.) For example:

   module M {

typedef long ArgType;

const long I = 10;

typedef short Y;

interface A {

struct S {

struct T {

ArgType x[I];

long y;

} m;

};

// ArgType and I introduced
// a new y is defined, the existing Y
// is not used

   typedef string ArgType; // Error: ArgType redefined enum I { I1, I2 }; // Error: I redefined typedef short Y; // OK

   }; // Potential scope of ArgType and I ends here

   interface B : A { typedef long ArgType // OK, redefined in derived interface struct S { // OK, redefined in derived interface

   ArgType x; // x is a long A::ArgType y; // y is a string }; }; };

   A type may not be redefined within its scope or potential scope, as shown in the preceding example. This rule prevents type names from changing their meaning throughout a non-module scope definition, and ensures that reordering of definitions in the presence of introduced types does not affect the semantics of a specification.

   Note that, in the following, the definition of M::A::U::I is legal because it is outside the potential scope of the I introduced in the definition of M::A::S::T::ArgType. However, the definition of M::A::I is still illegal because it is within the potential scope of the I introduced in the definition of M::A::S::T::ArgType.

   module M { typedef long ArgType; const long I = 10;

   interface A { struct S { struct T { ArgType x[I]; // ArgType and I introduced } m;

   };struct U {

   long I; // OK, I is not a type name }; enum I { I1, I2 }; // Error: I redefined

   }; // Potential scope of ArgType and I ends here };

   Note that redefinition of a type after use in a module is OK as in the example:

   typedef long ArgType; module M { struct S { ArgType x; // x is a long };

   typedef string ArgType; // OK! struct T { ArgType y; // Ugly but OK, y is a string }; };