This documentation is archived and is not being maintained.

7.4 Interior vs. Whole __gc Pointers

Visual Studio .NET 2003

All __gc pointers can point into the common language runtime heap, but they are divided into two kinds:

  • "Whole" __gc objects
  • "Interior" __gc pointers

The second kind of __gc pointer points to __gc sub-objects or value class objects.

Example

// __gc_pointers7.cpp
// compile with: /clr /LD
#using <mscorlib.dll>

__gc struct G {
   int i;
   G* next;
};

void f() {
   // pG is a whole object pointer
   G *pG = new G;
   // ipi is an interior pointer
   int __gc* ipi = &(pG->i);
   // ppG is an interior pointer
   G** ppG = &(pG->next);
   // *ppG is a whole object pointer
   *ppG = new G;
};

Note that although variables with type "__gc pointer to __value class" point to a whole __value class, they are nevertheless considered interior pointers; any __value class on the runtime heap must be embedded within a __gc object.

Characteristics

  • A "whole object" __gc pointer shall contain either the value 0 or a valid pointer into the common language runtime heap. If this condition is not met, the behavior is undefined.
  • An "interior" __gc pointer can be incremented or decremented.

Constraints

  • A "whole object" __gc pointer shall not be incremented or decremented.
  • An interior pointer type shall only be used in the declaration of a local variable, function parameter, or function return type.

    Example

    // __gc_pointers8.cpp
    // compile with: /clr /LD
    #using <mscorlib.dll>
    
    __gc struct G {
       int i;
       G* next;
    };
    
    __gc struct H {
       // int __gc* pi;   // error: member of __gc class 
    }; 
    
    // int __gc* gpi;   // error: global variable
    int * gnpi;   // ok: not a __gc pointer
    
    struct S {
       // int __gc* pi;   // error: member of unmanaged class
    };  
    
    int __gc* f();   // ok: function return type
    
    void d(int __gc* ppi) {   // ok: parameter type
       G *pG = new G;
       G** ppG = &(pG->next);   // ok: local variable
    };
    
    G** d(G *pG) {   // ok: function return type
       return (&pG->next);
    };
    
  • A __gc pointer shall not point to an interior __gc pointer.

Interior pointers require special handling by the garbage collector and therefore require more processing than pointers that point to "whole" objects. The common language runtime restricts the use of interior __gc pointers because of this expense.

Note that you can allocate value types that do not contain __gc pointers anywhere you can allocate a __nogc class. If one is allocated outside the runtime heap, it can be pointed to by a __nogc pointer.

Example

// __gc_pointers9.cpp
// compile with: /clr
#using <mscorlib.dll>
using namespace System;

__value struct V { int i; };

V glob_v;   // ok: V has no embedded __gc pointers
V __nogc* glob_pV = &glob_v;   // ok: no __gc pointers involved

int main() {
   glob_pV->i = 10;   
   Console::WriteLine( glob_v.i ); 
}

Output

10
Show: