VMS Help  —  CC  Language topics, 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.

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"}.

2  –  readonly

  Readonly variables are assigned the PSECT attribute NOWRT and are
  stored in the PSECT $READONLY$ 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.

3  –  _align

  The _align modifier allows you to align objects of any of the VSI 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 VSI 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.

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.

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

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

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) 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.

 On x86-64 systems, you link to the VSI C RTL by using the C RTL
 shareable image X86$$LIBRARY:DECC$SHR.EXE, which the linker
 automatically finds through IMAGELIB.OLB.

 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 VSI 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 VSI C RTL entry points are prefixed, link
 against the shareable image using the LINK command.  For example:

 $ CC/PREFIX_LIBRARY_ENTRIES=ALL_ENTRIES PROG1
 $ LINK PROG1

 The linker automatically searches IMAGELIB.OLB to find DECC$SHR.EXE,
 and resolves all C RTL references.  b.lm0 2
 Run-time_functions

  For help on the C run-time library (C RTL) functions supplied with
  your OpenVMS operating system, enter the following:

     $ HELP CRTL

  Also see the VSI C Run-Time Library Reference Manual for OpenVMS
  Systems.
Close Help