@c Copyright (C) 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, @c 1999, 2000, 2001 Free Software Foundation, Inc. @c This is part of the GCC manual. @c For copying conditions, see the file gcc.texi. @node VMS @chapter Using GCC on VMS @c prevent bad page break with this line Here is how to use GCC on VMS@. @menu * Global Declarations:: How to do globaldef, globalref and globalvalue with GCC. * VMS Misc:: Misc information. @end menu @node Global Declarations @section Global Declarations and VMS @findex GLOBALREF @findex GLOBALDEF @findex GLOBALVALUEDEF @findex GLOBALVALUEREF GCC does not provide the @code{globalref}, @code{globaldef} and @code{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: @smallexample #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 @end smallexample @noindent (The @code{_$$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 @file{GNU_HACKS.H}. An example of the usage is: @example GLOBALREF (int, ijk); GLOBALDEF (int, jkl, 0); @end example The macros @code{GLOBALREF} and @code{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: @example typedef int intvector[10]; GLOBALREF (intvector, foo); @end example 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 @code{GLOBALDEF} macro by hand. You may find a case where you wish to use the @code{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: @code{@{0,@}}, which will initialize the entire array to @code{0}. A shortcoming of this implementation is that a variable declared with @code{GLOBALVALUEREF} or @code{GLOBALVALUEDEF} is always an array. For example, the declaration: @example GLOBALVALUEREF(int, ijk); @end example @noindent declares the variable @code{ijk} as an array of type @code{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. @strong{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 ISO C feature allowing macros that expand to use the same name as the macro itself. @example GLOBALVALUEREF (int, ss$_normal); GLOBALVALUEDEF (int, xyzzy,123); #ifdef __GNUC__ #define ss$_normal ((int) ss$_normal) #define xyzzy ((int) xyzzy) #endif @end example Don't use @code{globaldef} or @code{globalref} with a variable whose type is an enumeration type; this is not implemented. Instead, make the variable an integer, and use a @code{globalvaluedef} for each of the enumeration values. An example of this would be: @example #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 @end example @node VMS Misc @section Other VMS Issues @cindex exit status and VMS @cindex return value of @code{main} @cindex @code{main} and the exit status GCC automatically arranges for @code{main} to return 1 by default if you fail to specify an explicit return value. This will be interpreted by VMS as a status code indicating a normal successful completion. Version 1 of GCC did not provide this default. GCC on VMS works only with the GNU assembler, GAS@. You need version 1.37 or later of GAS in order to produce value debugging information for the VMS debugger. Use the ordinary VMS linker with the object files produced by GAS@. @cindex shared VMS run time system @cindex @file{VAXCRTL} Under previous versions of GCC, the generated code would occasionally give strange results when linked to the sharable @file{VAXCRTL} library. Now this should work. A caveat for use of @code{const} global variables: the @code{const} modifier must be specified in every external declaration of the variable in all of the source files that use that variable. Otherwise the linker will issue warnings about conflicting attributes for the variable. Your program will still work despite the warnings, but the variable will be placed in writable storage. @cindex name augmentation @cindex case sensitivity and VMS @cindex VMS and case sensitivity Although the VMS linker does distinguish between upper and lower case letters in global symbols, most VMS compilers convert all such symbols into upper case and most run-time library routines also have upper case names. To be able to reliably call such routines, GCC (by means of the assembler GAS) converts global symbols into upper case like other VMS compilers. However, since the usual practice in C is to distinguish case, GCC (via GAS) tries to preserve usual C behavior by augmenting each name that is not all lower case. This means truncating the name to at most 23 characters and then adding more characters at the end which encode the case pattern of those 23. Names which contain at least one dollar sign are an exception; they are converted directly into upper case without augmentation. Name augmentation yields bad results for programs that use precompiled libraries (such as Xlib) which were generated by another compiler. You can use the compiler option @samp{/NOCASE_HACK} to inhibit augmentation; it makes external C functions and variables case-independent as is usual on VMS@. Alternatively, you could write all references to the functions and variables in such libraries using lower case; this will work on VMS, but is not portable to other systems. The compiler option @samp{/NAMES} also provides control over global name handling. Function and variable names are handled somewhat differently with G++. The GNU C++ compiler performs @dfn{name mangling} on function names, which means that it adds information to the function name to describe the data types of the arguments that the function takes. One result of this is that the name of a function can become very long. Since the VMS linker only recognizes the first 31 characters in a name, special action is taken to ensure that each function and variable has a unique name that can be represented in 31 characters. If the name (plus a name augmentation, if required) is less than 32 characters in length, then no special action is performed. If the name is longer than 31 characters, the assembler (GAS) will generate a hash string based upon the function name, truncate the function name to 23 characters, and append the hash string to the truncated name. If the @samp{/VERBOSE} compiler option is used, the assembler will print both the full and truncated names of each symbol that is truncated. The @samp{/NOCASE_HACK} compiler option should not be used when you are compiling programs that use libg++. libg++ has several instances of objects (i.e. @code{Filebuf} and @code{filebuf}) which become indistinguishable in a case-insensitive environment. This leads to cases where you need to inhibit augmentation selectively (if you were using libg++ and Xlib in the same program, for example). There is no special feature for doing this, but you can get the result by defining a macro for each mixed case symbol for which you wish to inhibit augmentation. The macro should expand into the lower case equivalent of itself. For example: @example #define StuDlyCapS studlycaps @end example These macro definitions can be placed in a header file to minimize the number of changes to your source code.