DOC HOME SITE MAP MAN PAGES GNU INFO SEARCH PRINT BOOK
 

(gcc.info) Global Declarations

Info Catalog (gcc.info) Include Files and VMS (gcc.info) VMS (gcc.info) VMS Misc
 
 Global Declarations and VMS
 ===========================
 
    GCC does not provide the `globalref', `globaldef' and `globalvalue'
 keywords of VAX-C.  You can get the same effect with an obscure feature
 of GAS, the GNU assembler.  (This requires GAS version 1.39 or later.)
 The following macros allow you to use this feature in a fairly natural
 way:
 
      #ifdef __GNUC__
      #define GLOBALREF(TYPE,NAME)                      \
        TYPE NAME                                       \
        asm ("_$$PsectAttributes_GLOBALSYMBOL$$" #NAME)
      #define GLOBALDEF(TYPE,NAME,VALUE)                \
        TYPE NAME                                       \
        asm ("_$$PsectAttributes_GLOBALSYMBOL$$" #NAME) \
          = VALUE
      #define GLOBALVALUEREF(TYPE,NAME)                 \
        const TYPE NAME[1]                              \
        asm ("_$$PsectAttributes_GLOBALVALUE$$" #NAME)
      #define GLOBALVALUEDEF(TYPE,NAME,VALUE)           \
        const TYPE NAME[1]                              \
        asm ("_$$PsectAttributes_GLOBALVALUE$$" #NAME)  \
          = {VALUE}
      #else
      #define GLOBALREF(TYPE,NAME) \
        globalref TYPE NAME
      #define GLOBALDEF(TYPE,NAME,VALUE) \
        globaldef TYPE NAME = VALUE
      #define GLOBALVALUEDEF(TYPE,NAME,VALUE) \
        globalvalue TYPE NAME = VALUE
      #define GLOBALVALUEREF(TYPE,NAME) \
        globalvalue TYPE NAME
      #endif
 
 (The `_$$PsectAttributes_GLOBALSYMBOL' prefix at the start of the name
 is removed by the assembler, after it has modified the attributes of
 the symbol).  These macros are provided in the VMS binaries
 distribution in a header file `GNU_HACKS.H'.  An example of the usage
 is:
 
      GLOBALREF (int, ijk);
      GLOBALDEF (int, jkl, 0);
 
    The macros `GLOBALREF' and `GLOBALDEF' cannot be used
 straightforwardly for arrays, since there is no way to insert the array
 dimension into the declaration at the right place.  However, you can
 declare an array with these macros if you first define a typedef for the
 array type, like this:
 
      typedef int intvector[10];
      GLOBALREF (intvector, foo);
 
    Array and structure initializers will also break the macros; you can
 define the initializer to be a macro of its own, or you can expand the
 `GLOBALDEF' macro by hand.  You may find a case where you wish to use
 the `GLOBALDEF' macro with a large array, but you are not interested in
 explicitly initializing each element of the array.  In such cases you
 can use an initializer like: `{0,}', which will initialize the entire
 array to `0'.
 
    A shortcoming of this implementation is that a variable declared with
 `GLOBALVALUEREF' or `GLOBALVALUEDEF' is always an array.  For example,
 the declaration:
 
      GLOBALVALUEREF(int, ijk);
 
 declares the variable `ijk' as an array of type `int [1]'.  This is
 done because a globalvalue is actually a constant; its "value" is what
 the linker would normally consider an address.  That is not how an
 integer value works in C, but it is how an array works.  So treating
 the symbol as an array name gives consistent results--with the
 exception that the value seems to have the wrong type.  *Don't try to
 access an element of the array.*  It doesn't have any elements.  The
 array "address" may not be the address of actual storage.
 
    The fact that the symbol is an array may lead to warnings where the
 variable is used.  Insert type casts to avoid the warnings.  Here is an
 example; it takes advantage of the ANSI C feature allowing macros that
 expand to use the same name as the macro itself.
 
      GLOBALVALUEREF (int, ss$_normal);
      GLOBALVALUEDEF (int, xyzzy,123);
      #ifdef __GNUC__
      #define ss$_normal ((int) ss$_normal)
      #define xyzzy ((int) xyzzy)
      #endif
 
    Don't use `globaldef' or `globalref' with a variable whose type is
 an enumeration type; this is not implemented.  Instead, make the
 variable an integer, and use a `globalvaluedef' for each of the
 enumeration values.  An example of this would be:
 
      #ifdef __GNUC__
      GLOBALDEF (int, color, 0);
      GLOBALVALUEDEF (int, RED, 0);
      GLOBALVALUEDEF (int, BLUE, 1);
      GLOBALVALUEDEF (int, GREEN, 3);
      #else
      enum globaldef color {RED, BLUE, GREEN = 3};
      #endif
 
Info Catalog (gcc.info) Include Files and VMS (gcc.info) VMS (gcc.info) VMS Misc
automatically generated byinfo2html