VMS Help
CC, Language topics

 *Conan The Librarian (sorry for the slow response - running on an old VAX)

 Compaq C language topics

  1 - Block

  A block is a compound statement.  It allows more than one statement
  to appear where a single statement ordinarily is used.  It is made
  up of a list of declarations and statements, enclosed in braces:

           { [declaration ...] [statement ...] }

  The declaration list is optional; if it is included, all
  declarations of variables are local to the block and supersede
  previous declarations for the duration of the block.  A block is
  entered normally when control flows into it, or when a goto
  statement transfers control to a label at the beginning of the
  block.  Each time the block is entered normally, storage is
  allocated for auto or register variables.  If, on the other hand, a
  goto statement transfers control to a label inside the block or if
  the block is the body of a switch statement, these storage
  allocations do not occur.  Blocks can be used wherever single
  statements are valid -- for example, as the action clause of an if
  statement:

            if ( i < 1 )
               {                       /* BEGINNING OF BLOCK */
                  char x;
                  for (x = 'a';  x <= 'z';  x++)
                     printf("char = %c\n", x);
               }                       /* END OF BLOCK      */

  2 - Valid File Specifications

  In Compaq C source programs, you can include both OpenVMS and UNIX*
  style file specifications.  Combinations of the two specifications
  are not supported by Compaq C.

  Example of a valid UNIX* file specification:

       beatle!/dba0/lennon/songs.lis.3

  Example of an invalid UNIX* file specification:

       BEATLE::DBA0:[LENNON.C]/songs.lis.3

 ----------
 * UNIX is a trademark of The Open Group.

  3 - Data Types

  The data type of an object must be specified in its declaration.
  The fundamental data types are the scalar types:

  short int           16-bit signed integer
  signed short int    16-bit signed integer
  unsigned short int  16-bit unsigned integer
  int                 32-bit signed integer
  signed int          32-bit signed integer
  unsigned int        32-bit unsigned integer
  long int            32-bit signed integer
  signed long int     32-bit signed integer
  unsigned long int   32-bit unsigned integer
  char                8-bit signed integer
  signed char         8-bit signed integer
  unsigned char       8-bit unsigned integer
  wchar_t             Long character (32-bit unsigned integer)
  float               32-bit (single-precision) floating-point number
  double              64-bit (double-precision) floating-point number
  long float          Interchangeable with double, but usage is
                      obsolete
  _Bool               An unsigned int that has the value 0 or 1
  _Imaginary          A C99-specified data type.  In Compaq C, use of
                      the _Imaginary keyword produces a warning,
                      which is resolved by treating it as an ordinary
                      identifier.

  The signed keyword is the default.  Declaring an object with int,
  for example, is equivalent to declaring it with signed int.
  However, char declarations should be explicitly declared, as the
  compiler offers command-line options to change the default.  If in
  doubt, use signed char over char because signed char is more
  portable.

  Strings are arrays of characters terminated by the null character
  (\0).

  Also, view the contents of the <ints.h> header file for definitions
  of platform-specific integer types.

 3.1 - Array

  An array is an aggregate of subscripted elements of the same type.
  Elements of an array can have one of the fundamental data types or
  can be structures, unions, or other arrays (multidimensional
  arrays).  An array is declared using square brackets.  The
  following example declares array1 to be an array of 10 integers.
  The valid subscripts for array1 range from 0 to 9.

       int array1[10];

  The next example declares array2 to be a two-dimensional (2 by 3)
  array of integers:

       int array2[2][3];

  The elements are stored in row-major order as follows:

       array2[0][0], array2[0][1], ...  array2[1][2].

 3.2 - enum

  An enumerated type is used to restrict the possible values of an
  object to a predefined list.  Elements of the list are called
  enumeration constants.

  The main use of enumerated types is to explicitly show the symbolic
  names, and therefore the intended purpose, of objects that can be
  represented with integer values.  Objects of enumerated type are
  interpreted as objects of type signed int, and are compatible with
  objects of other integral types.  The compiler automatically
  assigns integer values to each of the enumeration constants,
  beginning with 0.

  An enumerated type is a set of scalar objects that have type names.
  Variables are declared with enum specifiers in the place of the
  type specifier.  An enumerated type can have one of the following
  forms:

       enum { enumerator,...  }
       enum tag { enumerator,...  }
       enum tag

  Each enumerator defines a constant of the enumerated type (tag).
  The enumerator list forms an ordered list of the type's values.
  Each enumerator has the form "identifier [= expression]", where the
  "identifier" is the name to be used for the constant value and the
  optional "expression" gives its integer equivalent.  If a tag
  appears but no list of enumerators, the enum-specifier refers to a
  previous definition of the enumerated type, identified by the tag.

  The following example declares an enumerated object
  'background_color' with a list of enumeration constants:

  enum colors { black, red, blue, green, } background_color;

  Later in the program, a value can be assigned to the object
  'background_color':

  background_color = red;

  In this example, the compiler automatically assigns the integer
  values as follows:  black = 0, red = 1, blue = 2, and green = 3.
  Alternatively, explicit values can be assigned during the
  enumerated type definition:

  enum colors { black = 5, red = 10, blue, green = black+2 };

  Here, black equals the integer value 5, red = 10, blue = 11, and
  green = 7.  Note that blue equals the value of the previous
  constant (red) plus one, and green is allowed to be out of
  sequential order.

  Because the ANSI C standard is not strict about assignment to
  enumerated types, any assigned value not in the predefined list is
  accepted without complaint.

 3.3 - Pointer

  A pointer in C is a variable that holds the address of another
  variable.  Pointers are declared with the asterisk operator.  For
  example:

       int i, *ip, *np;       /* i IS AN INTEGER, ip AND np ARE
                                 POINTERS TO INTEGERS           */

       The following operations are permitted on pointers:

       o  Assigning an address to the pointer (as in ip = &i;)

       o  Fetching the object of the pointer (by dereferencing the
          pointer) with the asterisk operator (i = *ip;, which
          assigns the addressed integer to i)

       o  Adding (as in ip += 5;, which makes ip point to the object
          that is five longwords away from the initial address in ip)

       o  Subtracting (as in i = np - ip;, which gives the number of
          objects separating the objects pointed to by np and ip)

 3.4 - Structure

  A structure is an aggregate of members whose data types can differ.
  Members can be scalar variables, arrays, structures, unions, and
  pointers to any object.  The size of a structure is the sum of the
  sizes of its members, which are stored in the order of their
  declarations.  Structures are defined with the keyword struct,
  followed by an optional tag, followed by a structure-declaration
  list in braces.  The syntax is:

       struct [identifier] { struct-declaration ...  }

  Each struct-declaration is a type specifier (type keyword, struct
  tag, union tag, enum tag, or typedef name) followed by a list of
  member declarators:

       type-specifier member-declarator,...  ;

  Each member declarator defines either an ordinary variable or a bit
  field:

       declarator
  or
       [declarator] :  constant-expression

  The following example declares a new structure employee with two
  structure variables bob and susan of the structure type employee:

  struct employee {
     char *name;
     int   birthdate; /* name, birthdate, job_code, and salary are */
     int   job_code;  /* treated as though declared with const.    */
     float salary;
     };

  struct employee bob, susan;

 3.5 - typedef

   Use the typedef keyword to define an abbreviated name, or
   synonym,  for a lengthy type definition.  Grammatically,
   typedef is a storage-class specifier, so it can precede any valid
   declaration.  In  such  a declaration, the identifiers name types
   instead of variables. For  example:

       typedef char CH, *CP, STRING[10], CF();

   In the scope of this declaration, CH is a synonym for "character,"
   CP  for "pointer to character," STRING for "10-element array of
   characters," and CF for "function returning a character." Each of
   the  type definitions can be used in that scope to declare
   variables. For example:

       CF     c;       /* c IS A FUNCTION RETURNING A CHARACTER */
       STRING s;       /* s IS A 10-CHARACTER STRING            */

 3.6 - Union

  A union is an aggregate of members whose data types can differ.
  Members can be scalar variables, arrays, structures, unions, and
  pointers to any object.  The size of a union is the size of its
  longest member plus any padding needed to meet alignment
  requirements.  All its members occupy the same storage.  Unions are
  defined with the union keyword, followed by an optional tag,
  followed by a union-declaration list in braces.  The syntax is:

       union [identifier] { union-declaration ...  }

  Each union-declaration is a type specifier (type keyword, struct
  tag, union tag, enum tag, or typedef name) followed by a list of
  member declarators:

       type-specifier member-declarator,...  ;

  Each member declarator defines either an ordinary variable or a bit
  field:

       declarator
  or
       [declarator] :  constant-expression

  Once a union is defined, a value can be assigned to any of the
  objects declared in the union declaration.  For example:

       union name {
         dvalue;
         struct x { int value1; int value2; };
         float fvalue;
       } alberta;

       alberta.dvalue = 3.141596; /*Assigns pi to the union object*/

 Here, alberta can hold a double, struct, or float value.  The
 programmer has responsibility for tracking the current type
 contained in the union.  The type is maintained until explicitly
 changed.  An assignment expression can be used to change the type of
 value held in the union.

 3.7 - Void

  You can use the void data type to declare functions that do not
  return a value.  Functions declared to be of this type cannot
  contain return statements and cannot be used in statements where a
  return value is expected.  The void data type can be used in the
  cast operation if casting to a "function without a return value
  ...".  You can also use the void data type with pointers.

  4 - Declarations

  Declarations specify the functions and variables referenced in a
  program.  Declarations in C have the following syntax:

        declaration:

           declaration-specifiers [init-declarator-list];

        declaration-specifiers:

           storage-class-specifier [declaration-specifiers]
           type-specifier [declaration-specifiers]
           type-qualifier [declaration-specifiers]

        init-declarator-list:

           init-declarator
           init-declarator-list, init-declarator

        init-declarator:

           declarator
           declarator = initializer

  Note the following items about the general syntax of a declaration:

   o  The storage-class-specifier, type-qualifier, and type-specifier
      can be listed in any order.  All are optional, but, except for
      function declarations, at least one such specifier or qualifier
      must be present.  Placing the storage-class-specifier anywhere
      but at the beginning of the declaration is an obsolete style.

   o  Storage-class keywords are auto, static, extern, and register.

   o  Type qualifiers are const, volatile, and __restrict.

   o  The declarator is the name of the object being declared.  A
      declarator can be as simple as a single identifier, or can be a
      complex construction declaring an array, structure, pointer,
      union, or function (such as *x, tree(), and treebar[10]).

   o  Initializers are optional and provide the initial value of an
      object.  An initializer can be a single value or a
      brace-enclosed list of values, depending on the type of object
      being declared.

   o  A declaration determines the beginning of an identifier's
      scope.

   o  An identifier's linkage is determined by the declaration's
      placement and its specified storage class.

  Consider the following example:

       volatile static int var_number = 10;

 This declaration shows a qualified type (a type, int, with a type
 qualifier, volatile), a storage class (static), a declarator (data),
 and an initializer (10).  This declaration is also a definition,
 because storage is reserved for the data object var_number.

 For more information, see HELP CC LANGUAGE_TOPICS DATA_TYPES, HELP
 CC LANGUAGE_TOPICS STORAGE_CLASSES, and HELP CC LANGUAGE_TOPICS
 TYPE_QUALIFIERS.

 4.1 - Interpretation

  The symbols used in declarations are C operators, subject to the
  usual rules of precedence and associativity.  These operators are
  parentheses, brackets, and asterisks for "function returning...",
  "array of...", and "pointer to...", respectively.  Parentheses and
  brackets associate left to right; asterisk operators associate
  right to left.  Parentheses and brackets have the same precedence,
  which is higher than that of asterisks.  Parentheses are also used
  to change the associativity of the other operators.

  The following declaration, for example, is a "function returning a
  pointer to an array of pointers to char":

         char * ( *x() ) [];

  This is how the declaration is broken down to determine what it is:

         char * ( *x() ) [];

              * ( *x() ) [] is char
                ( *x() ) [] is (pointer to) char
                  *x()      is (array of) (pointer to) char
                   x()      is (pointer to) (array of) (pointer to)
                                char
                   x        is (function returning) (pointer to)
                               (array of) (pointer to) char

  In this sort of breakdown, lower precedence operators are removed
  first.  With two equal precedence operators, remove the rightmost
  if they are left-to-right operators, and the leftmost if they are
  right-to-left operators.  For example, "[]()" means "array of
  functions returning...".

  5 - Functions

  Functions consist of one or more blocks of statements that perform
  one logical operation.  They can be called from other functions
  either in the same program or in different programs.  A function
  may exchange values with the calling function by use of parameters.

  Function declarations have the following syntax:

       function_name()
  or
       function_name(arg1, arg2,...)
  or
       function_name(data-type arg1, data-type arg2,...)

  In the first form of the function declaration, the function takes
  no arguments.  In the second form, the function takes arguments;
  the arguments are declared outside the parameter list.  In the
  third form, the function declaration is a function prototype that
  specifies the type of its arguments in the identifier list; the
  prototype form is recommended.  In all three cases, the parenthesis
  after the function name are required.

  Compaq C for OpenVMS Systems provides a library of common
  functions.  These functions perform standard I/O operations,
  character and string handling, mathematical operations,
  miscellaneous system services, and UNIX* system emulation.  For
  more information, see HELP CC RUN-TIME_FUNCTIONS.

 ----------
 * UNIX is a trademark of The Open Group.

  6 - Builtin Functions

  Built-in functions allow you to directly access hardware and
  machine instructions to perform operations that are cumbersome,
  slow, or impossible in pure C.

  These functions are very efficient because they are built into the
  Compaq C compiler.  This means that a call to one of these
  functions does not result in a reference to a function in the C
  run-time library or in your programs.  Instead, the compiler
  generates the machine instructions necessary to carry out the
  function directly at the call site.  Because most of these built-in
  functions closely correspond to single VAX or Alpha machine
  instructions, the result is small, fast code.

  Some of these functions (such as those that operate on strings or
  bits) are of general interest.  Others (such as the functions
  dealing with process context) are of interest if you are writing
  device drivers or other privileged software.  Some of the functions
  are privileged and unavailable to user mode programs.

  Be sure to include the <builtins.h> header file in your source
  program to access these built-in functions.

  Compaq C supports the #pragma builtins preprocessor directive for
  compatibility with VAX C, but it is not required.

  Some of the built-in functions have optional arguments or allow a
  particular argument to have one of many different types.  To
  describe different valid combinations of arguments, the description
  of each built-in function may list several different prototypes for
  the function.  As long as a call to a built-in function matches one
  of the prototypes listed, the call is valid.  Furthermore, any
  valid call to a built-in function acts as if the corresponding
  prototype was in scope, so the compiler performs the argument
  checking and argument conversions specified by that prototype.

  The majority of the built-in functions are named after the machine
  instruction that they generate.  For more information on these
  built-in functions, see the documentation on the corresponding
  machine instruction.  In particular, see that reference for the
  structure of queue entries manipulated by the queue built-in
  functions.

  The Compaq C for OpenVMS VAX built-in functions use enumerated
  typedefs to define possible return values.  We recommend that you
  use the enumerated types to store and compare return values.

 6.1 - Add Aligned Word Interlocked

  The _ADAWI function adds its source operand to the destination.
  This operation is interlocked against similar operations by other
  processors or devices in the system.

  Syntax:

       typedef enum {_adawi_sum_neg=-1, _adawi_sum_zero,
                     _adawi_sum_pos} _ADAWI_STATUS;

       _ADAWI_STATUS _ADAWI(short __src, short *__dest);

 6.2 - ALLOCA

  Allocates n bytes from the stack and returns a pointer to the
  allocated memory.

  Syntax:

       void *__ALLOCA (unsigned int n);

 6.3 - Branch on Bit Clear-Clear Interlocked

  The _BBCCI function performs the following functions in interlocked
  fashion:

   o  Returns the complement of the bit specified by the two
      arguments

   o  Clears the bit specified by the two arguments

  Syntax:

       typedef enum {_bbcci_oldval_1, _bbcci_oldval_0} _BBCCI_STATUS;

       _BBCCI_STATUS _BBCCI(int __position, void *__address);

 6.4 - Branch on Bit Set-Set Interlocked

  The _BBSSI function performs the following functions in interlocked
  fashion:

   o  Returns the status of the bit specified by the two arguments

   o  Sets the bit specified by the two arguments

  Syntax:

       typedef enum {_bbssi_oldval_0, _bbcci_oldval_1} _BBSSI_STATUS;

       _BBSSI_STATUS _BBSSI(int __position, void *__address);

 6.5 - Find First Clear Bit

  The _FFC function finds the position of the first clear bit in a
  field.  The bits are tested for clear status starting at bit 0 and
  extending to the highest bit in the field.

  Syntax:

       typedef enum {_ff_bit_not_found, _ff_bit_found} _FF_STATUS;

       _FF_STATUS _FFC(int __start, char __size, const void * __base,
                       int *__position);

 6.6 - Find First Set Bit

  The _FFS function finds the position of the first set bit in a
  field.  The bits are tested for set status starting at bit 0 and
  extending to the highest bit in the field.

  Syntax:

       typedef enum {_ff_bit_not_found, _ff_bit_found} _FF_STATUS;

       _FF_STATUS _FFS(int __start, char __size, const void *__base,
                       int *__position);

 6.7 - Halt

  The _HALT function halts the processor when executed by a process
  running in kernel mode.  This is a privileged function.

  Syntax:

       void _HALT(void);

 6.8 - Insert Entry into Queue at Head Interlocked

  The _INSQHI function inserts an entry into the front of a queue in
  an indivisible manner.  This operation is interlocked against
  similar operations by other processors or devices in the system.

  Syntax:

       typedef enum {_insqi_inserted_many, _insqi_not_inserted,
                     _insqi_inserted_only} _INSQI_STATUS;

       _INSQI_STATUS _INSQHI(void *__new_entry, void *__head);

 6.9 - Insert Entry into Queue at Tail Interlocked

  The _INSQTI function inserts an entry at the end of a queue in an
  indivisible manner.  This operation is interlocked against similar
  operations by other processors or devices in the system.

  Syntax:

       typedef enum {_insqi_inserted_many, _insqi_not_inserted,
                     _insqi_inserted_only} _INSQI_STATUS;

       _INSQI_STATUS _INSQTI(void *__new_entry, void *__head);

 6.10 - Insert Entry in Queue

  The _INSQUE function inserts a new entry into a queue following an
  existing entry.

  Syntax:

       typedef enum {_insque_inserted_only, _insque_inserted_many}
                     _INSQUE_STATUS;

       _INSQUE_STATUS _INSQUE(void *__new_entry, void
                              *__predecessor);

 6.11 - Locate Character

  The _LOCC function locates the first character in a string matching
  the target character.

  Syntax:

       unsigned short _LOCC(char __target, unsigned short __length,
                            const char *__string, ...);

  where the optional argument (...) is char **position.

 6.12 - Move from Processor Register

  The _MFPR function returns the contents of a processor register.
  This is a privileged function.

  Syntax:

       void _MFPR(int register_num, int *destination);
       void _MFPR(int register_num, unsigned int *destination);

 6.13 - Move Character 3 Operand

  The _MOVC3 function copies a block of memory.  It is the preferred
  way to copy a block of memory to a new location.

  Syntax:

       void _MOVC3(unsigned short __length, const char *__src, char
                   *__dest, ...);

  where the ... is one or two optional arguments:

   o  char **endscr

   o  char **enddest

 6.14 - Move Character 5 Operand

  The _MOVC5 function allows the source string specified by the
  pointer and length pair to be moved to the destination string
  specified by the other pointer and length pair.  If the source
  string is smaller than the destination string, the destination
  string is padded with the specified character.

  Syntax:

       void _MOVC5(unsigned short __srclen, const char *__src, char
                   __fill, unsigned short __destlen, char *__dest,
                   ...);

  where the ... is one to three optional arguments:

   o  unsigned short *unmoved_src

   o  char ** endscr

   o  char **enddest

 6.15 - Move from Processor Status Longword

  The _MOVPSL function stores the value of the Processor Status
  Longword (PSL).

  Syntax:

       void _MOVPSL(void *__psl);

 6.16 - Move to Processor Register

  The _MTPR function loads a value into one of the special processor
  registers.  It is a privileged function.

  Syntax:

       int _MTPR(int src, int register_num);

 6.17 - Probe Read Accessibility

  The _PROBER function checks to see if you can read the first and
  last byte of the given address and length pair.

  Syntax:

       typedef enum {_probe_not_accessible, _probe_accessible}
                     _PROBE_STATUS;

       _PROBE_STATUS _PROBER(char __mode, unsigned short __length,
                             const void *__address);

 6.18 - Probe Write Accessibility

  The _PROBEW function checks the write accessibility of the first
  and last byte of the given address and length pair.

  Syntax:

       typedef enum {_probe_not_accessible, _probe_accessible}
                     _PROBE_STATUS;

       _PROBE_STATUS _PROBEW(char __mode, unsigned short __length,
                             const void *__address);

 6.19 - Read General-Purpose Register

  The _READ_GPR function returns the value of a general-purpose
  register.

  Syntax:

       int _READ_GPR(int register_number);

 6.20 - Remove Entry from Queue at Head Interlocked

  The _REMQHI function removes the first entry from the queue in an
  indivisible manner.  This operation is interlocked against similar
  operations by other processors or devices in the system.

  Syntax:

       typedef enum {_remqi_removed_more, _remqi_not_removed,
                     _remqi_removed_empty, _remqi_empty}
                     _REMQI_STATUS;

       _REMQI_STATUS _REMQHI(void *__head), void *__removed_entry);

 6.21 - Remove Entry from Queue at Tail Interlocked

  The _REMQTI function removes the last entry from the queue in an
  indivisible manner.  This operation is interlocked against similar
  operations by other processors or devices in the system.

  Syntax:

       typedef enum {_remqi_removed_more, _remqi_not_removed,
                     _remqi_removed_empty, _remqi_empty}
                     _REMQI_STATUS;

       _REMQI_STATUS _REMQTI(void *__head, void *__removed_entry);

 6.22 - Remove Entry from Queue

  The _REMQUE function removes an entry from a queue.

  Syntax:

       typedef enum {_remque_removed_more, _remque_removed_empty,
                     _remque_empty} _REMQUE_STATUS;

       _REMQUE_STATUS _REMQUE(void *__entry, void *__removed_entry);

 6.23 - Scan Characters

  The _SCANC function locates the first character in a string with
  the desired attributes.  The attributes are specified through a
  table and a mask.

  Syntax:

       unsigned short _SCANC(unsigned short __length, const char
                             *__string, const char *__table, char
                             __mask, ...);

  where the optional argument (...) is char **match.

 6.24 - Skip Character

  The _SKPC function locates the first character in a string that
  does not match the target character.

  Syntax:

       unsigned short _SKPC(char __target, unsigned short __length,
                            const char *__string, ... );

  where the optional argument (...) is char **position.

 6.25 - Span Characters

  The _SPANC function locates the first character in a string without
  certain attributes.  The attributes are specified through a table
  and a mask.

  Syntax:

       unsigned short _SPANC(unsigned short __length, const char
                             *__string, const char *__table, char
                             __mask, ...);

  where the optional argument (...) is char **mask.

  7 - Variable Length Argument Lists

  The set of functions and macros defined and declared in the
  <varargs.h> and the <stdarg.h> header files provide a method of
  accessing variable-length argument lists.  (Note that the
  <stdarg.h> functions are defined by the ANSI C standard and are,
  therefore, portable as compared with those defined in <varargs.h>.)

  The Compaq C RTL functions such as printf and execl, for example,
  use variable-length argument lists.  User-defined functions with
  variable-length argument lists that do not use <varargs.h> or
  <stdarg.h> are not portable due to the different argument-passing
  conventions of various machines.

  To use these functions and macros in <stdarg.h>, you must include
  the <stdarg.h> header file with the following preprocessor
  directive:

       #include <stdarg.h>

  The <stdarg.h> header file declares a type (va_list) and three
  macros (va_start, va_arg, and va_end) for advancing through a list
  of function arguments of varying number and type.  The macros have
  the following syntax:

       void va_start(va_list ap, parmN);

       type va_arg(va_list ap, type);

       void va_end(va_list ap);

  The va_start macro initializes the object ap of type va_list for
  subsequent use by va_arg and va_end.  The va_start macro must be
  invoked before any access to the unnamed arguments.  The parameter
  parmN is the identifier of the rightmost parameter in the variable
  parameter list of the function definition.  If parmN is declared
  with the register storage class, with a function or array type, or
  with a type that is not compatible with the type that results after
  application of the default arguments promotions, the behavior is
  undefined.  The va_start macro returns no value.

  The va_arg macro expands to an expresion that has the type and
  value of the next argument in the call.  The parameter ap is the
  same as the one initialized by va_start.  Each invocation of va_arg
  modifies ap so that the values of successive arguments are returned
  in turn.  The parameter "type" is a type name specified such that
  the type of a pointer to an object that has the specified type can
  be obtained by postfixing an asterisk (*) to "type".  If there is
  no actual next argument, or if type is not compatible with the type
  of the next actual argument (as promoted according to the default
  argument promotions), the behavior is undefined.  The first
  invocation of va_arg after that of va_start returns the value of
  the argument after that specified by parmN.  Successive invocations
  return the values of the remaining arguments in turn.

  The va_end macro facilitates a normal return from the function
  whose variable argument list was referred to by the expansion of
  va_start that initialized the va_list ap object.  The va_end macro
  can modify ap) so that it can no longer be used (without an
  intervening invocation of va_start).  If there is no corresponding
  invocation of va_start or if va_end is not invoked before the
  return, the behavior is undefined.  The va_end macro returns no
  value.

  8 - Preprocessor

  The Compaq C preprocessor uses directives to affect the compilation
  of a source file.  For Compaq C on OpenVMS systems, these
  directives are processed by an early phase of the compiler, not by
  a separate program.

  The preprocessor directives begin with a number sign (#) and do not
  end with a semicolon.  The number sign must appear in the first
  column of the source line.

 8.1 - Null directive (#)

  A preprocessing directive of the form # <newline> is a null
  directive and has no effect.

 8.2 - Conditional Compilation

  Conditional compilation is provided by the following directives:

  #if constant-expression
     Checks whether the constant expression is nonzero (true).

  #ifdef identifier
     Checks whether the identifier is defined.

  #ifndef identifier
     Checks whether the identifier is undefined.

  #else
     Introduces source lines to be compiled as an alternative to the
     conditions tested by the previous directives.

  #elif constant-expression
     Delimits alternative source lines to be compiled if the constant
     expression in the corresponding #if, #ifdef, or #ifndef
     directive is false and if the additional constant expression
     presented in the #elif directive is true.  An #elif directive is
     optional.

  #endif
     Ends the scope of the previous directives.

  If the condition checked by #if, #ifdef, or #ifndef is true, then
  all lines between the #else, #elif, and #endif are ignored.  If the
  condition is false, then any lines between the conditional
  directive and the #else or #elif (if any) are ignored.  If there is
  no #else, then the lines between the conditional and the #endif are
  ignored.

 8.3 - #define

  The #define preprocessor directive has the form:

       #define identifier token-string

  The preprocessor substitutes the token string everywhere in the
  program that it finds the identifier except within comments,
  character constants, or string constants.

  Macro replacements are defined in a #define directive of the
  following form:

       #define name([parm1[,parm2,...]]) token-string

  Within the program, all macro references that have the following
  form are replaced by the token string.  The arguments in the macro
  reference replace the corresponding parameters in the token string.

       name([arg1[,arg2,...]])

 8.4 - #dictionary

  The #dictionary directive is retained for compatibility with VAX C
  and is supported only when running the Compaq C compiler in VAX C
  mode (/STANDARD=VAXC).  See also the ANSI C equivalent #pragma
  dictionary directive.

  The #dictionary directive extracts Common Data Dictionary (CDD)
  definitions from the specified dictionary.  These definitions are
  then translated into Compaq C and included in the program.

  The #dictionary directive has the following form:

       #dictionary "cdd_path"

  The cdd_path is a character string that gives the path name of the
  CDD record.  It can also be a macro that resolves to such a
  character string.

 8.5 - #error

  The #error directive issues an optional diagnostic message, and
  ends compilation.  This directive has the following form:

       #error [message] <newline>

 8.6 - #include

  The #include directive instructs the preprocessor to insert the
  contents of the specified file or module into the program.  An
  #include directive can have one of three forms:

       #include "filespec"
       #include <filespec>
       #include module-name

  The first two forms are ANSI-compliant methods of file inclusion
  and are therefore more portable.  In these forms, .h is the default
  file type, unless the compiler is instructed to supply no default
  type (that is, a type of just ".") by the
  /ASSUME=NOHEADER_TYPE_DEFAULT qualifier.

  The third form is specific to OpenVMS systems for specifying the
  inclusion of a module from a text library, and is not generally
  needed or recommended because the ANSI forms also cause the text
  libraries to be searched.

  For the order of search, see /INCLUDE_DIRECTORY.

  There is no defined limit to the nesting level of #include files
  and modules.

 8.7 - #line

  The #line directive applies a specified line number and optional
  file specification to the next line of source text.  This can be
  useful for diagnostic messages.  The #line directive has the
  following forms:

       #line integer-constant <newline>
       #line integer-constant "filename" <newline>
       #line pp-tokens <newline>

  In the first two forms, the compiler gives the line following a
  #line directive the number specified by the integer constant.  The
  optional filename in quotation marks indicates the name of the
  source file that the compiler will provide in its diagnostic
  messages.  If the filename is omitted, the file name used is the
  name of the current source file or the last filename specified in a
  previous #line directive.

  In the third form, macros in the #line directive are expanded
  before it is interpreted.  This allows a macro call to expand into
  the integer-constant, filename, or both.  The resulting #line
  directive must match one of the other two forms, and is then
  processed as appropriate.

 8.8 - #module

  The #module directive is retained for compatibility with VAX C and
  is supported only when running the Compaq C compiler in VAX C mode
  (/STANDARD=VAXC).  See also the ANSI C equivalent #pragma module
  directive.

  The #module directive passes information about an object module to
  the compiler.

  The #module directive can have one of the following forms:

       #module identifier identifier
       #module identifier string

  The first argument of the directive is a Compaq C identifier or
  macro that resolves to an identifier.  It gives the
  system-recognized (for example, internally recognized by the
  debugger and the librarian) name of the module; the object file
  name remains the same.  The second argument specifies the optional
  identification that appears on listings.  This may be either a VAX
  C identifier, a character-string constant with no more than 31
  characters, or a macro that resolves to one of these.

  There can be only one #module directive per compilation.  It can
  appear anywhere before the C language text.

 8.9 - #pragma

  The #pragma directive performs compiler-specific tasks as
  designated by each implementation of the C language.

  All pragmas have a <pragma-name>_m version, which makes the pragma
  subject to macro replacement.  For example, #pragma assert is not
  subject to macro expansion, but #pragma assert_m is.

  Compaq C for OpenVMS Systems supports the following pragmas:

  #pragma assert[_m]

      Lets you specify assertions that the compiler can make about a
      program to generate more efficient code.  Can also be used to
      verify that certain compile-time conditions are met; this is
      useful in detecting conditions that could cause run-time
      faults.

      The #pragma assert directive is never needed to make a program
      execute correctly, however if a #pragma assert is specified,
      the assertions must be valid or the program might behave
      incorrectly.

      Syntax:

      #pragma assert non_zero(constant-expression) string-literal

      When the compiler encounters this directive, it evaluates the
      constant-expression.  If the expression is zero, the compiler
      generates a message that contains both the specified
      string-literal and the compile-time constant-expression.  For
      example:

      #pragma assert non_zero(sizeof(a) == 12) "a is the wrong size"

      In this example, if the compiler determines that the sizeof a
      is not 12, the following diagnostic message is output:

      CC-W-ASSERTFAIL, The assertion "(sizeof(a) == 12)" was not
      true. a is the wrong size.

      The #pragma assert non_zero directive can appear either inside
      or outside a function body.  When used inside a function body,
      the pragma can appear wherever a statement can appear, but the
      pragma is not treated as a statement.  When used outside a
      function body, the pragma can appear anywhere a declaration can
      appear, but the pragma is not treated as a declaration.

      Because macro replacement is not performed on #pragma assert,
      you might need to use the #pragma assert_m directive to obtain
      the results you want.  Consider the following program that
      verifies both the size of a struct and the offset of one of its
      elements:

      #include <stddef.h>
      typedef struct {
          int a;
          int b;
      } s;
      #pragma assert non_zero(sizeof(s) == 8) "sizeof assert failed"
      #pragma assert_m non_zero(offsetof(s,b) == 4) "offsetof assert
      failed"

      Because offsetof is a macro, the second pragma must be #pragma
      assert_m so that offsetof will expand correctly.

  #pragma builtins[_m]

      Enables the Compaq C built-in functions that directly access
      processor instructions.

      The #pragma builtins directive is provided for VAX C
      compatibility.

      Compaq C implements #pragma builtins by including the
      <builtins.h> header file, and is equivalent to #include
      <builtins.h> on OpenVMS systems.

      This header file contains prototype declarations for the
      built-in functions that allow them to be used properly.  By
      contrast, VAX C implemented this pragma with special-case code
      within the compiler, which also supported a #pragma nobuiltins
      preprocessor directive to turn off the special processing.
      Because declarations cannot be "undeclared", Compaq C does not
      support #pragma nobuiltins.  Furthermore, the names of all the
      built-in functions use a naming convention defined by ANSI C to
      be in a namespace reserved to the C language implementation.

  #pragma dictionary[_m]

      Allows you to extract CDD data definitions and include these
      definitions in your program.

      The ANSI C compliant #pragma dictionary directive is equivalent
      to the VAX C compatible #dictionary directive, but is supported
      in all compiler modes.  (The #dictionary directive is retained
      for compatibility and is supported only when compiling with the
      /STANDARD=VAXC qualifier.)

      Syntax:

           #pragma dictionary "cdd_path" [null_terminate]
           [name(structure_name)] [text1_to_array | text1_to_char]

      The cdd_path is a character string that gives the path name of
      the CDD record.  It can also be a macro that resolves to such a
      character string.

      The optional null_terminate keyword can be used to specify that
      all string data types should be null-terminated.

      The optional name() can be used to supply an alternate tag name
      or a declarator, struct_name for the outer level of a CDD
      structure.

      The optional text1_to_char keyword forces the CDD type "text"
      to be translated to char, rather than "array of char" if the
      size is 1.  This is the default if null_terminate is not
      specified.

      The optional text1_to_array keyword forces the CDD type "text"
      to be translated to type "array of char" even when the size
      is 1.  This is the default when null_terminate is specified.

  #pragma environment[_m]

       Sets, saves, or restores the states of context pragmas.  This
       directive protects include files from contexts set by
       encompassing programs, and protects encompassing programs from
       contexts that could be set in header files that they include.

       The #pragma environment directive affects the following
       pragmas:

        o  #pragma extern_model

        o  #pragma extern_prefix

        o  #pragma member_alignment

        o  #pragma message

        o  #pragma names

        o  #pragma pointer_size

        o  #pragma required_pointer_size

       Syntax:

           #pragma environment command_line
           #pragma environment header_defaults
           #pragma environment restore
           #pragma environment save

      command_line

           Sets, as specified on the command line, the states of all
           the context pragmas.  You can use this pragma to protect
           header files from environment pragmas that take effect
           before the header file is included.

      header_defaults

           Sets the states of all the context pragmas to their
           default values.  This is almost equivalent to the
           situation in which a program with no command-line options
           and no pragmas is compiled, except that this pragma sets
           the pragma message state to #pragma nostandard, as is
           appropriate for header files.

      save

           Saves the current state of every pragma that has an
           associated context.

      restore

           Restores the current state of every pragma that has an
           associated context.

  #pragma extern_model[_m]

       Controls the compiler's interpretation of objects that have
       external linkage.  This pragma lets you choose the global
       symbol model to be used for externs.

       Syntax:

           #pragma extern_model common_block [attr[,attr]...]
           #pragma extern_model relaxed_refdef [attr[,attr]...]
           #pragma extern_model strict_refdef "name" [attr[,attr]...]
           #pragma extern_model strict_refdef
           #pragma extern_model globalvalue
           #pragma extern_model save
           #pragma extern_model restore

      The default model on Compaq C is #pragma relaxed_refdef noshr.
      This is different from the model used by VAX C, which is common
      block, shr.

      The [attr[,attr]...] are optional psect attribute
      specifications chosen from the following (at most one from each
      line):

       o  gbl lcl (Not allowed with relaxed_refdef)

       o  shr noshr

       o  wrt nowrt

       o  pic nopic (Not meaningful for Alpha)

       o  ovr con

       o  rel abs

       o  exe noexe

       o  vec novec

       o  2 long 3 quad 4 octa 9 page

      See the Compaq C User's Guide for more information on the
      #pragma extern_model directive.

  #pragma extern_prefix[_m]

       Controls the compiler's synthesis of external names, which the
       linker uses to resolve external name requests.

       When you specify #pragma extern_prefix with a string argument,
       the compiler prepends the string to all external names
       produced by the declarations that follow the pragma
       specification.

       This pragma is useful for creating libraries where the
       facility code can be attached to the external names in the
       library.

       Syntax:

           #pragma extern_prefix "string" [(id[,id]...)]
           #pragma extern_prefix  save
           #pragma extern_prefix  restore

      Where "string" prepends the quoted string to external names in
      the declarations that follow the pragma specification.

      You can also specify an extern prefix for specific identifiers
      using the optional list [(<emphasis>(id)[,<emphasis>(id)]...)].

      The save and restore keywords can be used to save the current
      pragma prefix string and to restore the previously saved pragma
      prefix string, respectively.

      The default external prefix, when none has been specified by a
      pragma, is the null string.

  #pragma [no]inline[_m]

      Expands function calls inline.  The function call is replaced
      with the function code itself.

      Syntax:

           #pragma inline (id,...)
           #pragma noinline (id,...)

      If a function is named in an inline directive, calls to that
      function will be expanded as inline code, if possible.

      If a function is named in a noinline directive, calls to that
      function will not be expanded as inline code.

      If a function is named in both an inline and a noinline
      directive, an error message is issued.

      For calls to functions named in neither an inline nor a
      noinline directive, DEC C expands the function as inline code
      whenever appropriate as determined by a platform-specific
      algorithm.

  #pragma [no]member_alignment[_m]

      Tells the compiler to align structure members on the next
      boundary appropriate to the type of the member rather than the
      next byte.  For example, a long variable is aligned on the next
      longword boundary; a short variable on the next word boundary.

      Syntax:

           #pragma nomember_alignment [base_alignment]
           #pragma member_alignment [save | restore]

      The optional base_alignment parameter can be used with #pragma
      nomember_alignment to specify the base alignment of the
      structure.  Use one of the following keywords to specify the
      base_alignment:

       o  BYTE (1 byte)

       o  WORD (2 bytes)

       o  LONGWORD (4 bytes)

       o  QUADWORD (8 bytes)

       o  OCTAWORD (16 bytes)

      The optional save and restore keywords can be used to save the
      current state of the member_alignment and to restore the
      previous state, respectively.  This feature is necessary for
      writing header files that require member_alignment or
      nomember_alignment, or that require inclusion in a
      member_alignment that is already set.

  #pragma message[_m]

      Controls the issuance of individual diagnostic messages or
      groups of messages.  Use of this pragma overrides any
      command-line options that may affect the issuance of messages.

      Syntax:

           #pragma message option1 message-list
           #pragma message option2
           #pragma message (quoted-string)

      where option1 is:

         disable             Suppresses the issuance of the indicated
                             messages.

                             Only messages of severity Warning (W) or
                             Information (I) can be disabled.  If the
                             message has severity of Error (E) or
                             Fatal (F), it is issued regardless of
                             any attempt to disable it.

         enable              Enables the issuance of the indicated
                             messages.

         emit_once           Emits the specified messages only once
                             per compilation.

         emit_always         Emits the specified messages at every
                             occurrence of the condition.

         error               Sets the severity of each message in the
                             message-list to Error.

         fatal               Sets the severity of each message on the
                             message-list to Fatal.

         informational       Sets the severity of each message in the
                             message-list to Informational.

         warning             Sets the severity of each message in the
                             message-list to Warning.

      The message-list can be any one of the following:

       o  A single message identifier (within parentheses or not).

       o  A single message-group name (within parentheses or not).
          Message-group names are:

             ALL             All the messages in the compiler

             ALIGNMENT       Messages about unusual or inefficient
                             data alignment.

             C_TO_CXX        Messages reporting the use of C features
                             that would be invalid or have a
                             different meaning if compiled by a C++
                             compiler.

             CDD             Messages about CDD (Common Data
                             Dictionary) support.

             CHECK           Messages reporting code or practices
                             that, although correct and perhaps
                             portable, are sometimes considered
                             ill-advised because they can be
                             confusing or fragile to maintain.  For
                             example, assignment as the test
                             expression in an "if" statement.

                             NOTE:  The check group gets defined by
                             enabling level5 messages.

             DEFUNCT         Messages reporting the use of obsolete
                             features:  ones that were commonly
                             accepted by early C compilers but were
                             subsequently removed from the language.

             NEWC99          Messages reporting the use of the new
                             C99 Standard features.

             NOANSI          Messages reporting the use of non-ANSI
                             Standard features.  The NOANSI message
                             group is a synonym for NOC89.  Also see
                             message groups NEWC99, NOC89, NOc99.

             NOC89           Messages reporting the use of non-C89
                             Standard features.

             NOC99           Messages reporting the use of non-C99
                             Standard features.

             OBSOLESCENT     Messages reporting the use of features
                             that are valid in ANSI Standard C, but
                             which were identified in the standard as
                             being obsolescent and likely to be
                             removed from the language in a future
                             version of the standard.

             OVERFLOW        Messages that report assignments and/or
                             casts that can cause overflow or other
                             loss of data significance.

             PERFORMANCE     Messages reporting code that might
                             result in poor run-time performance.

             PORTABLE        Messages reporting the use of language
                             extensions or other constructs that
                             might not be portable to other compilers
                             or platforms.

             PREPROCESSOR    Messages reporting questionable or
                             non-portable use of preprocessing
                             constructs.

             QUESTCODE       Messages reporting questionable coding
                             practices.  Similar to the check group,
                             but messages in this group are more
                             likely to indicate a programming error
                             rather than just a non-robust style.
                             Enabling the QUESTCODE group provides
                             lint-like checking.

             RETURNCHECKS    Messages related to function return
                             values.

             UNINIT          Messages related to using uninitialized
                             variables.

             UNUSED          Messages reporting expressions,
                             declarations, header files, CDD records,
                             static functions, and code paths that
                             are not used.

                             Note, however, that unlike any other
                             messages, these messages must be enabled
                             on the command line
                             (/WARNINGS=ENABLE=UNUSED) to be
                             effective.

      o  A single message-level name (within parentheses or not).

         Note:  There is a core of very important compiler messages
         that are enabled by default, regardless of anything
         specified with /WARNINGS or #pragma message.  Referred to as
         message level 0, it includes all messages issued in header
         files, and comprises what is known as the nostandard group.
         All other message levels add additional messages to this
         core of enabled messages.

         You cannot disable level 0.  However, you can disable
         individual messages in level 0 that are not errors or
         fatals.

         Message-level names are:

           LEVEL1          Important messages.  These are less
                           important than level 0, because messages
                           in this group are not displayed if #pragma
                           nostandard is active.

           LEVEL2          Moderately important messages.  This level
                           is used to introduce new messages that
                           will be output in the DIGITAL UNIX V4.0
                           release.  LEVEL2 is the default for
                           DIGITAL UNIX and Tru64 UNIX platforms.

           LEVEL3          Less important messages.  In general,
                           these are the messages output by default
                           in DEC C Version 5.5 for OpenVMS Systems.
                           LEVEL3 is the default message level for
                           Compaq C for OpenVMS systems.

           LEVEL4          Useful check/portable messages.

           LEVEL5          Not so useful check/portable messages.

           LEVEL6          All messages in LEVEL5 plus additional
                           "noisy" messages.

        Enabling a level also enables all the messages in the levels
        below it.  So enabling LEVEL3 messages also enables messages
        in LEVEL2 and LEVEL1.

        Disabling a level also disables all the messages in the
        levels above it.  So disabling LEVEL4 messages also disables
        messages in LEVEL5 and LEVEL6.

      o  A comma-separated list of message identifiers, group names,
         and messages levels, freely mixed, enclosed in parentheses.

     option2 is:

           save -- saves the current state of which messages are
           enabled and disabled.

           restore -- restores the previous state of which messages
           are enabled and disabled.

     The save and restore options are useful primarily within header
     files.

     The #pragma message (quoted-string) form outputs the
     quoted-string as a compiler message.  This form of the pragma is
     subject to macro replacement.  For example, the following is
     valid:

        #pragma message ("Compiling file " __FILE__)

  #pragma module[_m]

      The ANSI C compliant #pragma module directive is equivalent to
      the VAX C compatible #module directive, but is supported in all
      compiler modes.  (The #module directive is retained for
      compatibility and is supported only when compiling with the
      /STANDARD=VAXC qualifier.) The #pragma module directive is
      specific to Compaq C for OpenVMS Systems and is not portable.

      Use the #pragma module directive to change the
      system-recognized module name and version number.  You can find
      the module name and version number in the compiler listing file
      and the linker load map.

      Syntax:

           #pragma module identifier identifier
           #pragma module identifier string

      The first parameter must be a valid Compaq C identifier.  It
      specifies the module name to be used by the linker.  The second
      parameter specifies the optional identification that appears on
      listings and in the object file.  It must be either a valid
      Compaq C identifier of 31 characters or less, or a
      character-string constant of 31 characters or less.

      Only one #pragma module directive can be processed per
      compilation unit, and that directive must appear before any C
      language text.  The #pragma module directive can follow other
      directives, such as #define, but it must precede any function
      definitions or external data definitions.

  #pragma names[_m]

      Provides the same kinds of control over the mapping of external
      identifiers' object-module symbols as does the /NAMES
      command-line qualifier, and it uses the same keywords (except
      that the "lowercase" keyword is not supported).  But as a
      pragma, the controls can be applied selectively to regions of
      declarations.

      This pragma should only be used in header files and is intended
      for use by developers who supply libraries and/or header files
      to their customers.

      The pragma has a save/restore stack that is also managed by
      #pragma environment, and so it is well-suited for use in header
      files.  The effect of #pragma environment header_defaults is to
      set NAMES to "uppercase,truncated", which is the compiler
      default.

      Syntax:

           #pragma names <stack-option>
           #pragma names <case-option>
           #pragma names <length-option>

      Where

      <stack-option> is one of:

       o  save - save the current names state

       o  restore - restore a saved names state

      <case-option> is one of:

       o  uppercase - uppercase external names

       o  as_is - do not change case

      <length-option> is one of:

       o  truncated - truncate at 31 characters

       o  shortened - shorten to 31 using CRC

  #pragma pack[_m]

      Specifies the byte boundary for packing members of C
      structures.

      Syntax:

           #pragma pack [n]

      The n specifies the new alignment restriction in bytes:

          1 - align to byte

          2 - align to word

          4 - align to longword

          8 - align to quadword

          16 - align to octaword

      A structure member is aligned to either the alignment specified
      by #pragma pack or the alignment determined by the size of the
      structure member, whichever is smaller.  For example, a short
      variable in a structure gets byte-aligned if #pragma pack 1 is
      specified.  If #pragma pack 2, 4, or 8 is specified, the short
      variable in the structure gets aligned to word.

      When #pragma pack is specified with a value of 0, packing
      reverts to that specified by the /[NO]MEMBER_ALIGNMENT
      qualifier setting (either explicit or default) on the command
      line.

  #pragma [no]standard[_m]

      Directs the compiler to define regions of source code where
      portability diagnostics are not to be issued.

      Use #pragma nostandard to suppress diagnostics about non-ANSI C
      extensions, regardless of the /STANDARD qualifier specified,
      until a #pragma standard directive is encountered.

      Use #pragma standard to reinstate the setting of the /STANDARD
      qualifier that was in effect before before the last #pragma
      nostandard was encountered.

      Every #pragma standard directive must be preceded by a
      corresponding #pragma nostandard directive.

      Note that this pragma does not change the current mode of the
      compiler or enable any extensions not already supported in that
      mode.

 8.10 - #undef

  The #undef directive cancels a previously defined macro
  replacement.  Any other macro replacements that occurred before the
  #undef directive remain.

  The #undef directive has the following syntax:

       #undef identifier

  9 - Predefined Macros

  In addition to the ANSI-compliant, implementation-independent
  macros described in the Compaq C Language Reference Manual, Compaq
  C for OpenVMS systems provides the following predefined macros:

 9.1 - System Identification Macros

  Each implementation of the Compaq C compiler automatically defines
  macros that you can use to identify the system on which the program
  is running.  These macros can assist in writing code that executes
  conditionally, depending on the architecture or operating system on
  which the program is running.

  The following table lists the traditional and new spellings of
  these predefined macro names for Compaq C on OpenVMS systems.  Both
  spellings are defined for each macro unless ANSI C mode is in
  effect (/STANDARD=ANSI89), in which case only the new spellings are
  defined.

        Traditional spelling      New spelling

             vms                   __vms
             VMS                   __VMS
             vms_version           __vms_VERSION
             VMS_VERSION           __VMS_VERSION
                                   __VMS_VER
                                   __DECC_VER
                                   __DECCXX_VER
             vax                   __vax
             VAX                   __VAX
             vaxc                  __vaxc
             VAXC                  __VAXC
             vax11c                __vax11C
             VAX11C                __VAX11C
              ---                  __DECC
              ---                  __STDC__
                                   __STDC_HOSTED__
                                   __STDC_VERSION__
                                   __STDC_ISO_10646__
                                   __MIA

  Note that __STDC__ is defined only in strict ANSI C mode.

  Predefined macros (with the exception of vms_version, VMS_VERSION,
  __vms_version and __VMS_VERSION) are defined as 1 or 0, depending
  on the system you're compiling on (VAX or Alpha processor), the
  compiler defaults, and the qualifiers used.  For example, if you
  compiled using G_floating format, then __D_FLOAT and __IEEE_FLOAT
  (Alpha processors only) are predefined to be 0, and __G_FLOAT is
  predefined as if the following were included before every
  compilation unit:

  #define  __G_FLOAT  1

  These macros can assist in writing code that executes
  conditionally.  They can be used in #elif, #if, #ifdef, and #ifndef
  directives to separate portable and nonportable code in a Compaq C
  program.  The vms_version, VMS_VERSION, __vms_version, and
  __VMS_VERSION macros are defined with the value of the OpenVMS
  version on which you are running (for example, Version 6.0).

 9.2 - Compiler Mode Macros

  The following predefined macros are defined as 1 if the
  corresponding compiler mode is selected (Otherwise, they are
  undefined):

  __DECC_MODE_STRICT     !  /STANDARD=ANSI89
  __DECC_MODE_RELAXED    !  /STANDARD=RELAXED_ANSI89
  __DECC_MODE_VAXC       !  /STANDARD=VAXC
  __DECC_MODE_COMMON     !  /STANDARD=COMMON
  __STDC__               !  /STANDARD=ANSI89, /STANDARD=RELAXED_ANSI89
  __STDC_VERSION__       !  /STANDARD=ISOC94
  __MS                   !  /STANDARD=MS

 9.3 - Floating Point Macros

  Compaq C automatically defines the following predefined macros
  pertaining to the format of floating-point variables.  You can use
  them to identify the format with which you are compiling your
  program:

  __D_FLOAT
  __G_FLOAT

 9.4 - RTL Standards Macros

  Compaq C defines the following macros that you can explicitly
  define (using the /DEFINE qualifier or the #define preprocessor
  directive) to control which Compaq C RTL functions are declared in
  header files and to obtain standards conformance checking:

  _XOPEN_SOURCE_EXTENDED
  _XOPEN_SOURCE
  _POSIX_C_SOURCE
  _ANSI_C_SOURCE
  _VMS_V6_SOURCE
  _DECC_V4_SOURCE
  __BSD44_CURSES
  __VMS_CURSES
  _SOCKADDR_LEN

 9.5 - HIDE FORBIDDEN NAMES

  The ANSI C standard specifies exactly what identifiers in the
  normal name space are declared by the standard header files.  A
  compiler is not free to declare additional identifiers in a header
  file unless the identifiers follow defined rules (the identifier
  must begin with an underscore followed by an uppercase letter or
  another underscore).

  When running the Compaq C compiler in strict ANSI C mode
  (/STANDARD=ANSI89), versions of the standard header files are
  included that hide many identifiers that do not follow the rules.
  The header file <stdio.h>, for example, hides the definition of the
  macro TRUE.  The compiler accomplishes this by predefining the
  macro __HIDE_FORBIDDEN_NAMES in strict ANSI mode.

  You can use the command line qualifier
  /UNDEFINE="__HIDE_FORBIDDEN_NAMES" to prevent the compiler from
  predefining this macro, thus including macro definitions of the
  forbidden names.

  The header files are modified to only define additional VAX C names
  if __HIDE_FORBIDDEN_NAMES is undefined.  For example, <stdio.h>
  might contain the following:

          #ifndef __HIDE_FORBIDDEN_NAMES
          #define TRUE    1
          #endif

 9.6 - CC$gfloat

  When you compile using the /G_FLOAT qualifier, CC$gfloat is defined
  as 1.  When you compile without the /G_FLOAT qualifier, CC$gfloat
  is defined as 0.  The CC$gfloat macro is provided for compatiblity
  with VAX C.  The __G_FLOAT predefined macro should be used instead.

 9.7 - DATE

  The __DATE__ macro evaluates to a string specifying the date on
  which the compilation started.  The string presents the date in the
  form "Mmm dd yyyy" The names of the months are those generated by
  the asctime library function.  The first d is a space if dd is less
  than 10.

  Example:

       printf("%s",__DATE__);

 9.8 - FILE

  The __FILE__ macro evaluates to a string literal specifying the
  file specification of the current source file.

  Example:

       printf("file %s", __FILE__);

 9.9 - LINE

  The __LINE__ macro evaluates to a decimal constant specifying the
  number of the line in the source file containing the macro
  reference.

  Example:

       printf("At line %d in file %s", __LINE__, __FILE__);

 9.10 - TIME

  The __TIME__ macro evaluates to a string specifying the time that
  the compilation started.  The time has the following format:

       hh:mm:ss

  Example:

       printf("%s", __TIME__);

  The value of this macro remains constant throughout the translation
  unit.

  10 - Predeclared Identifiers

 10.1 - __func__

  The __func__ predeclared identifier evaluates to a static array of
  char, initialized with the spelling of the function's name.  It is
  visible anywhere within the body of a function definition.

  Example:

       void foo(void) {printf("%s\n", __func__);}

  This function prints "foo".

  11 - Statements

  Statements are the executable instructions performed by the
  program.  Statements produce values and control program flow.  A
  group of statements enclosed in braces makes up a block.

  Any valid expression or declaration terminated by a semicolon is
  considered a statement.  The statements that control program flow
  are described in further HELP frames.

  See also HELP CC LANGUAGE_TOPICS DECLARATION and HELP CC
  LANGUAGE_TOPICS PREPROCESSOR.

 11.1 - break

  The break statement terminates the immediately enclosing while, do,
  for, or switch statement.  Control passes to the statement
  following the terminated statement.
  Syntax:

       break ;

 11.2 - continue

  The continue statement passes control to the test portion of the
  immediately enclosing while, do, or for statement.
  Syntax:

       continue ;

  In each of the following statements, a continue statement is
  equivalent to "goto label;":

    while (expression) { statement ... label: ; }

    do { statement ... label: ; } while (expression);

    for (expression; expression; expression)
        { statement ... label: ; }

  The continue statement is not intended for switches.  A continue
  statement inside a switch statement inside a loop causes
  reiteration of the loop.

 11.3 - do

  The do statement executes a statement one or more times, as long as
  a stated condition expression is true.
  Syntax:

       do statement while ( expression ) ;

  The do statement is executed at least once.  The expression is
  evaluated after each execution of the statement.  If the expression
  is not 0, the statement is executed again.  The statement following
  the do statement (the body of the do statement) is not optional;
  the null statement (a lone semicolon) is provided for specifying a
  do statement with an empty body.

 11.4 - for

  The for statement executes a statement zero or more times, with
  three specified control expressions.  Expression-1 is evaluated
  only once, before the first iteration; expression-2 is evaluated
  before every iteration; expression-3 is evaluated after every
  iteration.  The for loop terminates if, on evaluation, expression-2
  is 0.
  Syntax:

       for ( [expression-1] ; [expression-2] ; [expression-3] )
           statement

  The for statement is equivalent to the following format:

       expression-1;
       while ( expression-2 ) { statement expression-3; }

  You can omit any of the three expressions.  If expression-2 is
  omitted, the while condition is true.

 11.5 - goto

  The goto statement transfers control unconditionally to a labeled
  statement.
  Syntax:

       goto identifier ;

  The identifier must be a label located in the current function.
  You may use goto to branch into a block, but no initializations are
  performed on variables declared in the block.

 11.6 - if

  The if statement is a conditional statement.  It can be written
  with or without an else clause as follows:

       if ( expression ) statement
       if ( expression ) statement else statement

  In both cases, the expression is evaluated, and if it is not 0, the
  first statement is executed.  If the else clause is included and
  the expression is 0, the statement following else is executed
  instead.  In a series of if-else clauses, the else matches the most
  recent else-less if.

 11.7 - Labeled

  Any statement can be preceded by a label prefix of the following
  form:

       identifier:

  This declares the identifier as a label.  The scope of such a
  declaration is the current function.  Labels are used only as the
  targets of goto statements.

 11.8 - Null

  A null statement is a semicolon:

       ;

  The null statement provides a null action -- for example, the body
  of a for loop that takes no action:

       for(i=0; i < ARRAYSIZE && x[i] == 5; i++)
           ;

 11.9 - return

   The return statement causes a return from a function, with or
   without a  return value.
   Syntax:

       return ;
       return expression ;

  The return value is undefined if not specified in a return
  statement.  If an expression is specified in the return statement,
  it is evaluated and the value is returned to the calling function;
  the value is converted, if necessary, to the type with which the
  called function was declared.  If a function does not have a return
  statement, the effect (on reaching the end of the function) is the
  same as with a return statement that does not specify an
  expression.  Functions declared as void may not contain return
  statements specifying an expression.

 11.10 - switch

  The switch statement executes one or more of a series of cases,
  based on the value of an integer expression.
  Syntax:

       switch ( expression ) body

  The switch's body typically is a block, within which any statement
  can be prefixed with one or more case labels as follows:

       case constant-expression :

  At most one statement in the body may have the label as follows:

       default :

  The switch expression is evaluated and compared to the cases.  If
  there is a case matching the expression's value, it is executed; if
  not, the default case is executed.  The switch is normally
  terminated by a break, return, or goto statement in one of the
  cases.  If there is no matching case and no default, the body of
  the switch statement is skipped.

 11.11 - while

  The while statement executes a statement 0 or more times, as long
  as a stated condition is true.
  Syntax:

       while ( expression ) statement

  The expression is evaluated before each execution, and the
  statement is executed if the expression is not 0.  The statement
  following the parentheses (the body of the while statement) is not
  optional; the null statement (a lone semicolon) is provided for
  specifying a while statement with an empty body.

  12 - Storage Classes

  The storage class of a variable determines when its storage is
  allocated, whether its contents are preserved across different
  blocks or functions, and what link-time scope the variable has.

  Auto variables are allocated at run time.  They are not preserved
  across functions.  Auto is the default storage class for variables
  declared within a function.

  Extern variables are allocated at compile time.  They are preserved
  across functions.  There can be only 65,532 extern variables per
  program.  Extern is the default storage class for variables
  declared outside a function.

  Globaldef, globalref, and globalvalue variables are allocated at
  compile time.  They are preserved across functions.  The number of
  global symbols is unlimited.

  Register variables are allocated at run time.  They cannot be
  referenced from other separately compiled functions.

  Static variables are allocated at compile time.  If externally
  declared, they retain their values across functions.  If internally
  declared (inside of a function), they cannot be referenced from
  other functions; if control passes from the defining function, to
  other functions, and then passed back to the defining function, the
  variable retains its previous value and is not reinitialized.

  13 - Type Qualifiers

  Data-type qualifiers affect the allocation or access of data
  storage.  The data-type qualifiers are const, volatile, and
  __restrict.

 13.1 - const

  The const data-type qualifier restricts access to stored data.  If
  you declare an object to be of type const, you cannot modify that
  object.  You can use the const data-type qualifier with the
  volatile data-type qualifier or with any of the storage-class
  specifiers or modifiers.  The following example declares the
  variable x to be a constant integer:

       int const x;

 13.2 - volatile

  The volatile data-type qualifier prevents an object from being
  stored in a machine register, forcing it to be allocated in memory.
  This data-type qualifier is useful for declaring data that is to be
  accessed asynchronously.  A device driver application often uses
  volatile data storage.  Like const, you can specify the volatile
  data-type qualifier with any of the storage-class specifiers or
  modifiers with the exception of the register storage class.

 13.3 - __restrict

  The __restrict data-type qualifier is used to designate a pointer
  as pointing to a distinct object, thus allowing compiler
  optimizations to be made.

  14 - Storage Class Modifiers

  The storage-class modifiers allow individual attributes of a
  variable to change without changing the other default attributes
  connected with a given storage class.  Storage-class keywords and
  storage-class modifiers can be specified in either order.

  Syntax:

       modifier storage_class_keyword identifier;

  If you specify a storage-class modifier but not a storage class
  keyword, the storage class defaults to extern.

 14.1 - noshare

  Noshare variables are assigned the PSECT attribute NOSHR.  Noshare
  variables may not be shared between processes.  This modifier is
  used when linking variables that are not to be shared within a
  shareable image.  You can use the noshare modifier with the
  storage-class keywords static, [extern], globaldef, and
  globaldef{"name"}.

 14.2 - readonly

  Readonly variables are assigned the PSECT attribute NOWRT and are
  stored in the PSECT $CODE, which is a nonwritable data area.  Other
  programs can access the PSECT directly, but none of the information
  can be overwritten.  You can use the readonly modifier with the
  storage-class keywords [extern], static, globaldef, and
  globaldef{"name"}.

  You can use both the readonly and noshare modifiers with the
  [extern] and the globaldef{"name"} specifiers.  If you use both
  modifiers with either the static or the globaldef specifiers, the
  compiler ignores noshare and accepts readonly.

 14.3 - _align

  The _align modifier allows you to align objects of any of the
  Compaq C data types on a specified storage boundary.  Use the
  _align modifier in a data declaration or definition.

  When specifying the boundary of the data alignment, you can use a
  predefined constant:  BYTE or byte, WORD or word, LONGWORD or
  longword, QUADWORD or quadword, OCTAWORD or octaword, and PAGE or
  page.

  You can also specify an integer value that is a power of two.  The
  power of two tells Compaq C the number of bytes to pad in order to
  align the data:

    For OpenVMS VAX systems, specify a constant 0, 1, 2, 3, 4, or 9.

    For OpenVMS Alpha systems, specify any constant from 0 to 16.

 14.4 - __align

  The __align storage-class modifier has the same semantic meaning as
  the _align keyword.  The difference is that __align is a keyword in
  all compiler modes while _align is a keyword only in modes that
  recognize VAX C keywords.  For new programs, using __align is
  recommended.

 14.5 - __forceinline

  Similar to the __inline storage-class modifier, the __forceinline
  storage-class modifier marks a function for inline expansion.
  However, using __forceinline on a function definition and prototype
  tells the compiler that it must substitute the code within the
  function definition for every call to that function.  (With
  __inline, such substitution occurs at the discretion of the
  compiler.)

  Syntax:

       __forceinline [type] function_definition

 14.6 - __inline

  The __inline modifier marks a function for inline expansion.  Using
  __inline on a function definition and prototype tells the compiler
  that it can substitute the code within the function definition for
  every call to that function.  Substitution occurs at the discretion
  of the compiler.  The __inline storage-class specifier has the same
  effect as the #pragma inline preprocessor directive, except that
  the latter attempts to provide inline expansion for all functions
  in a translation unit, rather than for selected functions.

  Syntax:

       __inline [type] function_definition

 14.7 - inline

  Similar to the __inline storage-class modifier, the inline
  storage-class modifier can be used as a declaration specifier in
  the declaration of a function.  This modifier is supported in
  relaxed ANSI C mode (/STANDARD=RELAXED_ANSI89) or if the
  /ACCEPT=C99_KEYWORDS or /ACCEPT=GCCINLINE qualifier is specified.

  With static functions, inline has the same effect as applying
  __inline or #pragma inline to the function.

  However, when inline is applied to a function with external
  linkage, besides allowing calls within that translation unit to be
  inlined, the inline semantics provide additional rules that also
  allow calls to the function to be inlined in other translation
  units or for the function to be called as an external function, at
  the compiler's discretion:

   o  If the inline keyword is used on a function declaration with
      external linkage, then the function must also be defined in the
      same translation unit.

   o  If all of the file scope declarations of the function use the
      inline keyword but do not use the extern keyword, then the
      definition in that translation unit is called an inline
      definition, and no externally-callable definition is produced
      by that compilation unit.

      Otherwise, the compilation unit does produce an
      externally-callable definition.

   o  An inline definition must not contain a definition of a
      modifiable object with static storage duration, and it must not
      refer to an identifier with internal linkage.  These
      restrictions do not apply to the externally-callable
      definition.

   o  As usual, at most one compilation unit in an entire program can
      supply an externally-callable definition of a given function.

   o  Any call to a function with external linkage may be translated
      as a call to an external function, regardless of the presence
      of the inline qualifier.  It follows from this and the previous
      point that any function with external linkage that is called
      must have exactly one externally-callable definition among all
      the compilation units of an entire program.

   o  The address of an inline function with external linkage is
      always computed as the address of the unique
      externally-callable definition, never the address of an inline
      definition.

   o  A call to inline function made through a pointer to the
      externally-callable definition may still be inlined or
      translated as a call to an inline definition, if the compiler
      can determine the name of the function whose address was stored
      in the pointer.

  2 Link_libraries
   Both the VAX C RTL and the Compaq C RTL can coexist on your
   OpenVMS VAX system.  The VAX C RTL supports existing VAX C
   applications.  The Compaq C RTL supports ANSI-compliant Compaq C
   and Compaq C++, as well as other components of the OpenVMS
   environment.  In addition, the
   Compaq C RTL provides a mechanism for thread safety, performance
   improvements, and problem fixes.

   Applications developed with VAX C will continue to use the
   VAX C RTL.  However, VAX C applications can be relinked to use
   the Compaq C RTL instead.  This lets you take advantage of the new
   features of the Compaq C RTL and solve potential interoperability
   problems in complex applications that incorporate both the VAX C
   and and the Compaq C RTLs.  Existing applications that are
   relinked to use the Compaq C RTL should be carefully tested for
   possible problems resulting from the differences in behavior
   between the VAX C RTL and the Compaq C RTL.  See the applicable
   Compaq C release notes and OpenVMS release notes for additional
   detail.

   Most linking needs should be satisfied by using the Compaq C RTL
   shareable image DECC$SHR.EXE in the SYS$LIBRARY directory.  Use
   this linking method for programs that are written entirely in
   Compaq C or Compaq C++ code; that is, with no VAX C object
   modules.

   Because DECC$SHR.EXE has only prefixed names (no unprefixed
   names), to successfully link against it, make sure you cause
   prefixing to occur for all Compaq C RTL entry points.  Do this by
   compiling in one of two ways:

   1.  Compile with the /PREFIX_LIBRARY_ENTRIES=ALL_ENTRIES
       qualifier.

   2.  Compile with the /STANDARD=VAXC or /STANDARD=COMMON qualifier;
       you get /PREFIX_LIBRARY_ENTRIES=ALL_ENTRIES as the default.

   After making sure that all Compaq C RTL entry points are prefixed,
   link against the shareable image using the LINK command.  For
   example:

   $ CC/DECC/PREFIX_LIBRARY_ENTRIES=ALL_ENTRIES PROG1
   $ LINK PROG1

   For a description of additional ways to link to the Compaq C RTL,
   see the Compaq C Run-Time Library Reference Manual for OpenVMS
   Systems.
  Close     HLB-list     TLB-list     Help  

[legal] [privacy] [GNU] [policy] [netiquette] [sponsors] [FAQ]
Tweet
Polarhome, production since 1999.
Member of Polarhome portal.