[an error occurred while processing this directive]

HP OpenVMS Systems

C Programming Language
Content starts here Compaq C

Compaq C
User's Guide for OpenVMS Systems


Previous Contents Index


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

x = a[x][y];

Notes

  • Because of operating system differences, the behavior of the run-time array-bounds checking is different on Tru64 UNIX systems than on OpenVMS systems.

    If there is no handler, an OpenVMS program fails with:


    %SYSTEM-F-SUBRNG, arithmetic trap, subscript out of range at
     PC=xxx, PS=xxx
    %TRACE-F-TRACEBACK, symbolic stack dump follows
    


    On Tru64 UNIX systems, the output would be:


    Trace/BPT trap (core dumped)
    


    Furthermore, to trap the error on OpenVMS systems, a user needs to write:


    signal(SIGFPE, handler);
    


    While on Tru64 UNIX systems, the equivalent line would be:


    signal(SIGTRAP, handler);
    
  • When run-time checking is enabled, the Compaq C compiler emits a bad check in certain cases. These cases arise when an array is accessed using pointer arithmetic and run-time array-bounds checking is enabled. In such a case, the compiler can output only the checking code for the first pointer-arithmetic operation performed on the array. This can result in an incorrect check if the resulting pointer value is again operated on by pointer arithmetic.

    Consider the following expression where a is a pointer, b is an array, and c and d are integers:


    a = b + c - d;
    


    When bounds checking is enabled, the compiler outputs a check to verify that c is within the bounds of the array. This leads to an incorrect run-time trap in cases where c is outside the bounds of the array and c - d is not.

    In these cases, the compiler outputs a diagnostic noting that the check code it produced is bad. You can then recode the pointer expression so that the integer part is in parentheses. In this way, the expression will contain only one pointer-arithmetic operation, and the compiler will output the correct check. In the previous example, the expression would be changed to:


    a = b + (c - d);
    

/CHECK=POINTER_SIZE (ALPHA ONLY)

Use /CHECK=POINTER_SIZE to direct the compiler to generate code that checks 64-bit pointer values (used in certain contexts where 32-bit pointers are also present) 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).

To control the types of pointer-size checks you want made, use one or more of the POINTER_SIZE option keywords shown in Table 1-5.

Table 1-5 /CHECK =POINTER_SIZE Qualifier Options
Option Usage
[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.

Specifying /CHECK=POINTER_SIZE defaults to /CHECK=POINTER_SIZE=(ASSIGNMENT,PARAMETER).

For information about compiler features that affect pointer size, see the following:

  • /POINTER_SIZE
  • #pragma pointer_size
  • #pragma required_pointer_size
  • __INITIAL_POINTER_SIZE predefined macro

The following contrived program contains a number of pointer assignments. The comment on each line indicates what /CHECK=POINTER_SIZE keyword to specify to enable checking for that line.


    #pragma required_pointer_size long
    int *a;
    char *b;
    typedef char * l_char_ptr;

    #pragma required_pointer_size short
    char *c;
    int *d;

    foo(int * e)              /* Check e if PARAMETER is specified. */
    {
        d = a;                /* Check a if ASSIGNMENT is specified. */
        c = (char *) a;       /* Check a if CAST is specified. */
        c = (char *) d;       /* No checking ever. */
        foo( a );             /* Check a if ASSIGNMENT is specified. */
        bar( a );             /* No checking ever - no prototype */
        b = (l_char_ptr) a;   /* No checking ever. */
        c = (l_char_ptr) a;   /* Check a if ASSIGNMENT is specified */
        b = (char *) a;       /* Check if CAST is specified. */
    }

Defaults

Omitting this qualifier defaults to /NOCHECK, which equates to /CHECK=(NOUNINITIALIZED_VARIABLE,NOBOUNDS,NOPOINTER_SIZE).

Specifying /CHECK defaults to /CHECK=(UNINITIALIZED_VARIABLES, BOUNDS, POINTER_SIZE), which equates to /CHECK=(UNINITIALIZED_VARIABLES, BOUNDS, POINTER_SIZE=(ASSIGNMENT,PARAMETER)).

/[NO]COMMENTS=option

Governs whether or not comments appear in preprocess output files and, if they are to appear, whether they appear themselves or are replaced by a single space.

Table 1-6 shows the /COMMENTS qualifier options.

Table 1-6 /COMMENTS Qualifier Options
Option Usage
AS_IS Specifies that the comment appears in the output file.
SPACE Specifies that a single space replaces the comment in the output file.

/NOCOMMENTS specifies that nothing replaces the comment in the output file. This can result in inadvertent token pasting.

The Compaq C preprocessor might replace a comment at the end of a line or on a line by itself with nothing, even if /COMMENTS=SPACE is specified. Doing so does not change the meaning of the program.

The default is /COMMENTS=SPACE for the ANSI89, RELAXED_ANSI89, and MIA modes of the compiler. The default is /NOCOMMENTS for all other compiler modes.

Specifying /COMMENTS on the command line defaults to /COMMENTS=AS_IS.

/[NO]CROSS_REFERENCE

Specifies whether the compiler generates cross-references for variable names.

If you specify /CROSS_REFERENCE, the compiler lists, for each variable referenced in the procedure, the line numbers of the lines on which the variable is referenced.

This qualifier has no effect unless you also specify /LIST and either /SHOW=SYMBOLS or /SHOW=BRIEF. The default is /NOCROSS_REFERENCE.

/[NO]DEBUG[=(option[,...])]

Includes information in the object module for use by the OpenVMS Debugger.

If the /DEBUG qualifier is not specified, the default is:

  • /DEBUG=(TRACEBACK,NOSYMBOLS) on Alpha systems.
  • /DEBUG=(TRACEBACK,NOINLINE,NOSYMBOLS) on VAX systems.

Specifying /DEBUG with no keywords is equivalent to specifying /DEBUG=ALL.

Table 1-7 describes the debugger options.

Table 1-7 Debugger Compilation Options
Option Usage
ALL Includes symbol table records and traceback records for both VAX and Alpha systems. On VAX systems, this also selects the behavior of the INLINE keyword.

On Alpha systems, /DEBUG=ALL is equivalent to /DEBUG=(TRACEBACK,SYMBOLS).

On VAX systems, /DEBUG=ALL is equivalent to /DEBUG=(TRACEBACK,SYMBOLS,INLINE).

INLINE (VAX ONLY) Generates debug information to cause a STEP command to STEP/INTO an inlined function call.
NOINLINE (VAX ONLY) Generates debug information to cause a STEP command to STEP/OVER an inlined function call.
NONE Does not include any debugging information. This is equivalent to /NODEBUG.
NOTRACEBACK Suppresses generation of traceback records.
NOSYMBOLS Suppresses generation of symbol table records.
SYMBOLS Generates symbol table records.
TRACEBACK Generates traceback records.

/DECC

Invokes the Compaq C compiler.

On OpenVMS VAX systems, the CC command is used to invoke either the VAX C or Compaq C compiler. If your system has a VAX C compiler already installed on it, the Compaq C installation procedure provides the option of specifying which compiler will be invoked by default when just the CC command is used. To invoke the compiler that is not the default, use the CC command with the appropriate qualifier: CC/DECC for the Compaq C compiler, or CC/VAXC for the VAX C compiler. If your system does not have a VAX C compiler installed on it, the CC command will invoke the Compaq C compiler.

On OpenVMS Alpha systems, specifying /DECC is equivalent to not specifying it; this qualifier is supported to provide compatibility with Compaq C on OpenVMS VAX systems.

/[NO]DEFINE=(identifier[=definition][,...])
/[NO]UNDEFINE=(identifier[,...])

Performs the same functions as the #define and #undef preprocessor directives. The /DEFINE qualifier defines a macro to be substituted for every occurrence of a given identifier in the compilation unit or units. The /UNDEFINE qualifier cancels a previous definition (but not subsequent ones). When both /DEFINE and /UNDEFINE are present in a compilation unit or on the CC command line, /DEFINE is evaluated before /UNDEFINE.

Since /DEFINE and /UNDEFINE are not part of the source file, they are not associated with a listing line number or source line number. Therefore, when an error occurs in a command-line definition, the message displayed at the terminal does not indicate a line number. In the listing file, these diagnostic messages are placed before the source listing in the order that they were encountered. When the expansion of a definition causes an error at a specific source line in the program, the diagnostics---both at the terminal and in the listing file---are associated with that source line.

A command line containing the /DEFINE and the /UNDEFINE qualifiers can be long. Continuation characters cannot appear within quotes or they will be included in the macro stream. The length of a CC command line cannot exceed the maximum length allowed by DCL.

The /NODEFINE and /NOUNDEFINE qualifiers are provided for compatibility with other DCL qualifiers. You can use these qualifiers to cancel /DEFINE or /UNDEFINE qualifiers that you have specified in a symbol that you use to compile Compaq C programs.

The defaults are /NODEFINE and /NOUNDEFINE.

Usage and Examples

Since the CC command line must be compatible with DCL, the syntax of the /DEFINE and /UNDEFINE qualifiers differs from the syntax of the #define and #undef preprocessor directives in the following way:

  • An equal sign is required after /DEFINE; a space is required after #define . For example, the following are equivalent:


    $
    
    CC/DEFINE=TRUE
    
    #define TRUE 1
    

    Note that the value of TRUE on the /DEFINE qualifier is automatically set to 1. Any other value must be specified. For example, the following are equivalent:


    $
    
    CC/DEFINE=MAYBE=2
    
    #define MAYBE 2
    
  • DCL converts all input to uppercase unless it is enclosed in quotation marks. For example, the following are equivalent:


    $
    
    CC/DEFINE=true
    
    #define TRUE 1
    
  • The macro defined on the /DEFINE qualifier must be enclosed in quotation marks if at least one of the following is true:
    • You want to preserve lowercase
    • The macro definition contains spaces or characters that would not be valid on the DCL command line.
    • The macro is a function-like macro

    For example:


    $
    
    CC/DEFINE="true"
             ! Preserves lowercase
    
    $
    
    CC/DEFINE="blank=' '"
        ! Contains and preserves the blank
    
    $
    
    CC/DEFINE="f1=a+b"
           ! Contains a '+' character
    
    $
    
    CC/DEFINE="funct(a)=2"
       ! Defines a function-like macro
    
  • Within a macro definition and inside quotation marks, a delimiter can be either an equal sign or a space, whichever comes first. If an equal sign is the delimiter, the following examples are equivalent:


    $
    
    CC/DEFINE="true=1"
    
    #define true 1
    

    If a space is the delimiter, the following examples are equivalent:


    $
    
    CC/DEFINE="true =1"
    
    #define true =1
    

    In this example, the space, preserved by the quotation marks, serves as the delimiter, assigning true a value of =1 , which is clearly not intended.
  • Within a definition and outside quotation marks, the only allowed delimiter is an equal sign; a space terminates the definition. The following definitions, for example, are not recognized by DCL:


    $ CC/DEFINE= TRUE
    $ CC/DEFINE=(FALSE 0)
    

    In the first example, DCL interprets TRUE as a file specification; in the second, DCL flags an invalid value specification.
  • When more than one /DEFINE is present on the CC command line or in a single compilation unit, only the last /DEFINE is used. Similarly, only the last /UNDEFINE on the CC command line or the compilation unit is used.

You can pass an equal sign to the compiler in any of the following ways:


$ CC/DEFINE=(EQU==,"equ =","equal==")

In the first definition, the first equal sign is removed by DCL as the delimiter; the second equal sign is passed to the compiler. In the second example, the space is recognized as a delimiter because the definition is inside quotes; therefore, only one equal sign is required. In the third definition, the first equal sign is recognized as the delimiter and is removed; the second equal sign is passed to the compiler.

You can pass quotation marks in any of the following ways:


$ CC/DEFINE=(QUOTES="""","funct(b)=printf(")")

In both examples, DCL removes the first and last quotation marks before passing the definition to the compiler.

Here is a simple use of the /UNDEFINE qualifier to cancel a previous definition of TRUE:


$ CC/UNDEFINE=TRUE

The /UNDEFINE qualifier is useful for undefining the predefined Compaq C preprocessor constants. For example, if you use a preprocessor system identification macro (such as __vaxc , __VAXC , __DECC , or __vms ) to conditionally compile segments of Compaq C specific code, you can undefine that constant to see how the portable sections of your program execute. Consider the following program:


main()
{
#if __DECC
printf("I'm being compiled with Compaq C on an OpenVMS system.");
#else
printf("I'm being compiled on some other compiler.");
#endif
}

This program produces the following output:


$ CC  EXAMPLE.C[Return]
$ LINK  EXAMPLE.OBJ[Return]
$ RUN  EXAMPLE.EXE[Return]
I'm being compiled with Compaq C on an OpenVMS system.
$ CC/UNDEFINE="__DECC" EXAMPLE [Return]
$ LINK  EXAMPLE.OBJ[Return]
$ RUN  EXAMPLE.EXE[Return]
I'm being compiled on some other compiler.

/[NO]DIAGNOSTICS[=file-spec]

Creates a file containing compiler messages and diagnostic information. The default file extension for a diagnostics file is .DIA. The diagnostics file is used with the Compaq Language-Sensitive Editor (LSE). To display a diagnostics file, enter the command REVIEW/FILE=file-spec while in LSE. For more information, see Appendix C. The default is /NODIAGNOSTICS.

/ENDIAN=option (ALPHA ONLY)

This qualifier takes the options BIG or LITTLE.

It controls whether big or little endian ordering of bytes is carried out in character constants. For example, consider the following declaration:


int foo = 'ABCD';

Specifying /ENDIAN=LITTLE places 'A' in the first byte, 'B' in the second byte, and so on.

Specifying /ENDIAN=BIG places 'D' in the first byte, 'C' in the second byte, and so on.

The default is /ENDIAN=LITTLE.

/[NO]ERROR_LIMIT[=n]

This qualifier limits the number of Error-level diagnostic messages that are acceptable during program compilation. Compilation terminates when the limit n is exceeded. /NOERROR_LIMIT specifies that there is no limit on error messages.

The default is /ERROR_LIMIT=30, which specifies that compilation terminates after 31 error messages.

/EXTERN_MODEL=option

In conjunction with the /[NO]SHARE_GLOBALS qualifier, controls the initial compiler model for external objects. Conceptually, the compiler behaves as if the first line of the program being compiled was a #pragma extern_model with the model and psect name, if any, specified by the /EXTERN_MODEL qualifier and with the shr or noshr keyword specified by the /[NO]SHARE_GLOBALS qualifier.

For example, assume the command line contains the following qualifiers:


/EXTERN_MODEL=STRICT_REFDEF="MYDATA"/NOSHARE

The compiler will behave as if the program begins with the following line:


#pragma extern_model strict_refdef "MYDATA" noshr

Table 1-8 describes the /EXTERN_MODEL qualifier options.

Table 1-8 /EXTERN_MODEL Qualifier Options
Option Usage
COMMON_BLOCK Sets the compiler's extern_model to the common_block model. This is the model traditionally used for extern data by VAX C.
RELAXED_REFDEF Sets the compiler's extern_model to the relaxed_refdef model. Some declarations are references and some are definitions. Multiple uninitialized definitions for the same object are allowed and are resolved into one by the linker. However, a reference requires that at least one definition exist.

This is the model used by the portable C compiler ( pcc ) on UNIX systems.

STRICT_REFDEF [=" name"] Sets the compiler's extern_model to the strict_refdef model. Some declarations are references and some are definitions. There must be exactly one definition in the program for any symbol referenced. The optional name, in quotation marks, is the name of the psect for any definitions.

This is the model specified by ANSI C. Use it in a program that is to be a strict ANSI C conforming program.

This model is the preferred alternative to the nonstandard storage-class keywords globaldef and globalref .

GLOBALVALUE Sets the compiler's extern_model to the globalvalue model. This model is similar to the strict_refdef model except that these global objects have no storage; instead, they are link-time constant values. There are two cases:
  • If the declaration is an ANSI C reference, the same object file records are produced as VAX C would produce for an uninitialized globalvalue .
  • If the declaration is an ANSI C definition, the same object records are produced as VAX C would produce for an initialized globalvalue .

This model is the preferred alternative to the nonstandard storage-class keyword globalvalue .

The default is /EXTERN_MODEL=RELAXED_REFDEF. This is different from VAX C, which uses the common block model for external objects.

/[NO]FIRST_INCLUDE=(file[,...]) (ALPHA ONLY)

Includes the specified files before any source files. This qualifier corresponds to the Tru64 UNIX -FI switch.

This qualifier is useful if you have command lines to pass to the C compiler that are exceeding the DCL command-line length limit. Using the /FIRST_INCLUDE qualifier can help solve this problem by replacing lengthy /DEFINE and /WARNINGS qualifiers with #define and #pragma message preprocessor directives placed in a /FIRST_INCLUDE file.

When /FIRST_INCLUDE=file is specified, file is included in the source as if the line before the first line of the source was:


#include "file"

If more than one file is specified, the files are included in their order of appearance on the command line.

The default is /NOFIRST_INCLUDE.

/FLOAT=option

Controls the format of floating-point variables.

On OpenVMS Alpha systems, representation of double variables defaults to G_floating format if not overridden by another format specified with the /FLOAT or /[NO]G_FLOAT qualifier.

If you are linking against object-module libraries, and /PREFIX=ALL is not specified on the command line:

  • a program compiled with G_FLOAT format must be linked with the object library VAXCRTL.OLB
  • a program compiled with D_FLOAT format must be linked with VAXCRTLD.OLB
  • a program compiled with IEEE_FLOAT format (ALPHA ONLY) must be linked with VAXCRTLT.OLB

The VAXCRTLX.OLB, VAXCRTLDX.OLB, and VAXCRTLTX.OLB libraries are used for the same floating-point formats, respectively, but include support for X_FLOAT format (/L_DOUBLE_SIZE=128). (ALPHA ONLY)

If /PREFIX=ALL is specified, then there is no need to link to the above-mentioned *.OLB object libraries. All the symbols you need are in STARLET.OLB. (ALPHA ONLY)

On OpenVMS VAX systems, representation of double variables defaults to D_floating format if not overridden by another format specified with the /FLOAT or /[NO]G_FLOAT qualifier. There is one exception: if /STANDARD=MIA is specified, G_floating is the default. If you are linking against object-module libraries, a program compiled with G_floating format must be linked with the object library DECCRTLG.OLB. (VAX ONLY)

Table 1-9 describes the /FLOAT qualifier options.

Table 1-9 /FLOAT Qualifier Options
Option Usage
D_FLOAT double variables are represented in D_floating format.
G_FLOAT double variables are represented in G_floating format.
IEEE_FLOAT (ALPHA ONLY) float and double variables are represented in IEEE floating-point format (S_float and T_float, respectively). Use the /IEEE_MODE qualifier for controlling the handling of IEEE exceptional values. If /IEEE_MODE is not specified, the default behavior is /IEEE_MODE=FAST.

/[NO]G_FLOAT

Controls the format of floating-point variables. The /[NO]G_FLOAT qualifier is replaced by the /FLOAT qualifier, but is retained for compatibility.


Previous Next Contents Index