VMS Help  —  CC  /CHECK
     /CHECK[=ALL|NONE|([NO]UNINITIALIZED_VARIABLES, [NO]BOUNDS,
          [NO]POINTER_SIZE[=(option,...)], [NO]FP_MODE, [NO]ARG_INFO)]
     /NOCHECK (D)

  This qualifier is for use only as a debugging aid.  It should not be used
  to build production code without carefully assessing its performance impact
  on the application in question for each platform on which the application
  runs.  For example, the I64-only FP_MODE check can add significant overhead
  to every function in the compilation, even if the application uses little
  or no floating point.

  /CHECK=NONE is equivalent to /NOCHECK.

  /CHECK=ALL is equivalent to
  /CHECK=(UNINITIALIZED_VARIABLES,BOUNDS,POINTER_SIZE=ALL,FP_MODE,ARG_INFO).

  /CHECK=UNINITIALIZED_VARIABLES initializes all automatic variables to the
  value 0x7ff580057ff58005.  This value is a double signaling NaN and, if
  used as a floating-point value in certain double operations, causes a
  floating-point trap if traps are enabled.  Traps are not enabled if the
  program is compiled /FLOAT=IEEE and the /IEEE value is something other than
  FAST.

  On I64 systems:

   o  Traps are not caused when values are converted to an integer type.

   o  The float type does not trap.

  /CHECK=BOUNDS enables run-time checking of array bounds.  Array-bounds
  processing is performed in the following way:

   o  Checks are done only when accessing an array.

   o  Checks are not done when accessing a pointer, even if that access is
      done using the subscript operator.  This means that checks are not done
      on arrays declared as formal parameters because they are considered
      pointers in the C language.  If a formal parameter is a multi-dimension
      array, all bounds except the first are checked.

   o  If an array is accessed using the subscript operator (as either the
      left or right operand), and the subscript operator is not the operand
      of an address-of operator, the check is for the index to be between 0
      and the number of array elements minus one, inclusive.

   o  If an array is accessed using the subscript operator (as either the
      left or right operand), and the subscript operator is the operand of
      the address-of operator, the check is for the index to be between 0 and
      the number of elements in the array, inclusive.

      The reason for treating the address-of case differently is that it is
      common programming practice to have a loop such as:

      int a[10];
      int *b;
      for (b = a ; b < &a[10] ; b++) { .... }

      In this case, access to &a[10] is allowed even though it is outside the
      range of the array.

   o  If the array is being accessed using pointer addition, the check is for
      the value being added to be between 0 and the number of elements in the
      array, inclusive.

   o  If the array is being accessed using pointer subtraction (that is, the
      subraction of an integer value from a pointer, not the subtraction of
      one pointer from another), the check is for the value being subtracted
      to be between the negation of the number of elements in the array and
      0, inclusive.

   o  In the previous three cases, an optional compile-time message (ident
      SUBSCRBOUNDS2) can be enabled to detect the case where an array has
      been accessed using either a constant subscript or constant pointer
      arithmetic, and the element accessed is exactly one past the end of the
      array.

   o  Bounds checking is not done for arrays declared with one element.
      (Because ANSI C does not allow arrays without dimensions inside
      structs, it is common practice to declare such arrays with a bounds
      specifier of 1.)

      In this case, an optional compile-time message (ident SUBSCRBOUNDS1)
      can be enabled to detect the case where an array declared with a single
      element is accessed using either a constant subscript or constant
      pointer arithmetic, and the element accessed is not part of the array.

   o  VSI C emits run-time checks for arrays indexed by constants, even
      though the compiler can and does detect this situation at compile-time.
      An exeption is that no run-time check is made if the compiler can
      determine that the access is valid.

   o  If a multi-dimension array is accessed, the compiler performs checks on
      each of the subscript expressions, making sure each is within the
      corresponding bound.  So for the following code, the compiler checks
      that both x and y are between 0 and 9.  It does not check that 10 * x +
      y is between 0 and 99:

      int a[10][10];
      int x,y,z;

      x = a[x][y];

  /CHECK=POINTER_SIZE directs the compiler to check 32-bit pointer values to
  make sure they will fit in a 32-bit pointer.  If such a value cannot be
  represented by a 32-bit pointer, the run-time code signals a range error
  (SS$_RANGEERR).

  Use one or more of the following POINTER_SIZE option keywords to determine
  the pointer-size checks you want made:

   [NO]ASSIGNMENT    Check whenever a 64-bit pointer is assigned to a
                     32-bit pointer (including use as an actual argument).

   [NO]CAST          Check whenever a 64-bit pointer is cast to a 32-bit
                     pointer.

   [NO]INTEGER_CAST  Check whenever a long pointer is cast to a 32-bit
                     integer.

   [NO]PARAMETER     Check all formal parameters at function startup to
                     make sure that all formal parameters declared to be
                     32-bit pointers are 32-bit values.

   ALL               Do all checks.

   NONE              Do no checks.

  /CHECK=FP_MODE generates code in the prologue of every function defined in
  the compilation to compare the current values of certain fields in the
  processor's floating-point status register (FPSR) with the values expected
  in those fields based on the command-line qualifiers with which the
  function was compiled.

  The values checked are the rounding mode and the trap-enable bits:

   o  If the rounding mode is not consistent with the value of the
      /ROUNDING_MODE qualifier specified at compile time, an informational
      message SYSTEM-I-FPMODERC is issued at runtime, citing the current mode
      and the compile-time specified mode (Note that /ROUNDING_MODE=DYNAMIC
      is treated the same as /ROUNDING_MODE=NEAREST for this purpose).

   o  If the trap-enable flags are not consistent with the setting of the
      /IEEE qualifier (for /FLOAT=IEEE_FLOAT compilations) or with the
      setting used to implement VAX floating types (for /FLOAT=G_FLOAT or
      /FLOAT=D_FLOAT compilations), an informational message
      SYSTEM-I-FPMODECTL is issued at run time, citing the current
      trap-enable flags as well as the trap-enable flags expected by the
      compilation.  To identify the point of failure, you need to rerun the
      program under DEBUG and issue "SET BREAK/EXCEPTION".

  Note that the checking code generated for /CHECK=FP_MODE includes a
  standard call to OTS$CHECK_FP_MODE within the prologue of each function,
  and OTS$CHECK_FP_MODE itself assumes the standard calling conventions
  (described in the OpenVMS Calling Standard).  Because of this, it is not
  possible to use this checking option when compiling function definitions
  that have a nonstandard linkage (see #pragma linkage and #pragma
  use_linkage) specifying conventional scratch registers with the PRESERVED
  or NOTUSED attribute.  Doing so will cause the compiler to issue the
  "REGCONFLICT" E-level diagnostic at the opening brace of such function
  definitions.  To compile such functions successfully, the FP_MODE keyword
  must be removed from the list of /CHECK= keywords.

  /CHECK=ARG_INFO generates code to verify the input parameters to functions
  defined in the compiled source.  This code checks for datatype consistency
  between the caller and its called function.

  When the runtime does parameter-type checking, it categorizes the actual
  type information into one of six possibilities:
     VAX single-precision floating-point
     VAX double-precision floating-point - D_floating
     VAX double-precision floating-point - G_floating
     IEEE single-precision floating-point
     IEEE double-precision floating-point
     none-of-the-above "bucket"

  It is only a mismatch of these types that is considered.  So while the
  run-time code will catch a case of a VAX D_floating number passed to a
  function that expects a VAX single-precision number, it will not detect the
  case of an int passed to a function that expects a long double type
  (because both int and long double are viewed as the same type; that is,
  they both fall into the none-of-the-above bucket).

  When a mismatch is found, a %SYSTEM-I-ARGTYP1 is output at runtime for each
  argument slot whose type does not match the expected type.

  This checking applies only to arguments passed in the first eight argument
  slots, and will not check that the number of arguments passed matches the
  number expected.

  If the /CHECK qualifier is omitted, the default is /NOCHECK, which equates
  to /CHECK=(NOUNINITIALIZED_VARIABLE, NOBOUNDS, NOPOINTER_SIZE, NOFP_MODE,
  NOARGINFO).

  If you specify /CHECK, the default is /CHECK=(UNINITIALIZED_VARIABLES,
  BOUNDS, POINTER_SIZE=(ASSIGNMENT,PARAMETER), FP_MODE, ARG_INFO).
Close Help