United States

Compaq C

# Compaq C
User's Guide for OpenVMS Systems

Previous | Contents | Index

The combined use of the `readonly` and `noshare` modifiers is ignored by the compiler in the following declarations:

    readonly  noshare  static  int  x;
    readonly  noshare  globaldef  int  x;

When it encounters a situation as shown in the previous example, the compiler ignores the `noshare` modifier and accepts `readonly` . The order of the storage-class specifier, the storage-class modifier, and the data-type keyword within a declaration is not significant.

The Compaq C compiler does static (global) initialization of pointers by using the .ADDRESS directive. By using this mechanism, the compiler efficiently generates position-independent code. The linker makes image sections that contain such initialization nonshareable.

# Chapter 5
Preprocessor Directives

The Compaq C preprocessor provides the ability to perform macro substitution, conditional compilation, and inclusion of named files. Preprocessor directives, lines beginning with `#` and possibly preceded by white space, are used to communicate with the preprocessor. The Compaq C Language Reference Manual describes the ANSI-compliant preprocessor directives available with the Compaq C compiler. This chapter describes the preprocessor directives that are either specific to Compaq C on OpenVMS systems, or that are used in an implementation-specific way:

- The `#dictionary` directive, used for CDD/Repository extraction ( Section 5.4.3, Section 5.1)
- The `#include` directive, used for file inclusion ( Section 5.2)
- The `#module` directive, for specifying an alternative name and identification for the object module ( Section 5.3, Section 5.4.13)
- The `#pragma` directive and pragmas specific to OpenVMS systems ( Section 5.4)

If you plan to port programs to and from other C implementations, take care in choosing which preprocessor directives to use within your programs. See the Compaq C Language Reference Manual for more information about using preprocessor directives for conditional compilation. For a complete discussion of portability concerns, see the Compaq C Run-Time Library Reference Manual for OpenVMS Systems.

Preprocessor directives are independent of the usual scope rules; they remain in effect from their occurrence until the end of the compilation unit. For more information about the compilation unit, see Chapter 1.

# 5.1 CDD/Repository Extraction (#dictionary)

The `#dictionary` directive is retained for compatibility with VAX C, and is supported only when running Compaq C in VAX C mode (/STANDARD=VAXC). See Section 5.4.3 for information on using the ANSI C equivalent `#pragma dictionary` directive.

# 5.2 File Inclusion (#include)

The `#include` directive inserts external text into the source stream delivered to the compiler. This directive is often used to include global definitions for use with Compaq C functions and macros in the program text.

The `#include` directive is supported on all Compaq C implementations, but the syntax and semantics vary. For example, the directory search algorithm for locating included files on OpenVMS systems differs from that on Tru64 UNIX systems, primarily because of differences in the native file systems and conventions on the two platforms. Nevertheless, by choosing the lowest common denominator of plain text files in directories to contain header files, you can define command-line options for both platforms to cause searching to be done in the same way. Compaq C for OpenVMS Systems also provides a form of the `#include` directive specifically for including text modules from OpenVMS text library files. The following sections describe the `#include` directive as implemented on OpenVMS systems.

The `#include` directives may be nested to a depth determined by the FILLM process quota and by virtual memory restrictions. The Compaq C compiler imposes no inherent limitation on the nesting level of inclusion.

OpenVMS and most UNIX style file specifications can be included in Compaq C source programs.

The following sections describe the different forms of the `#include` directive.

## 5.2.1 Inclusion Using Angle Brackets

The first form of the `#include` preprocessor directive uses angle brackets (<>) to delimit the file specification:

`#include <file-spec>`

The file-spec is a valid file specification or a logical name. A file specification may be up to 255 characters long.

If the file-spec contains "/" or "!" characters, it is assumed to be a UNIX style name, and the compiler attempts to combine it with other UNIX style names from the /INCLUDE_DIRECTORY command-line qualifier and translate the result to an OpenVMS file specification using RTL functions. Otherwise, the file-spec is treated as an OpenVMS file specification with defaults supplied from command-line qualifiers and logical names in a prescribed search order.

When specifying the names of files to be included in your source program, avoid directory specifications of the following form:

`DBA0:[.dir-name...]`

Depending on device logical names is not good practice. Instead, try to use only simple file names complete with the .h file type, and use the /INCLUDE_DIRECTORY qualifier to specify the directories to search.

For the angle-bracket form of inclusion, the compiler searches directories in the following order for the file to be included:

1. Any directories specified with the /INCLUDE_DIRECTORY qualifier.
2. The directory or search list of directories specified in the logical name DECC$SYSTEM_INCLUDE, if DECC$SYSTEM_INCLUDE is defined.
3. If DECC$SYSTEM_INCLUDE is not defined, then the directory or search list of directories specified by DECC$LIBRARY_INCLUDE.
4. If neither DECC$SYSTEM_INCLUDE nor DECC$LIBRARY_INCLUDE are defined as logical names, the compiler searches the following directories for plain text-file copies of compiler header files:

   > SYS$COMMON:[DECC$LIB.INCLUDE.DECC$RTLDEF]
   > SYS$COMMON:[DECC$LIB.INCLUDE.SYS$STARLET_C]

   Normally, the compiler installation does not put any files in these directories, but the compiler will search them if they exist.
5. If the file is still not found, all directories and the file extension are stripped off and the steps for including a module from a text library are followed.
6. If the file is still not found, SYS$LIBRARY is searched.

You can define DECC$SYSTEM_INCLUDE to be a valid directory specification or a search list of valid directory specifications. Before each compilation of your program, you can redefine DECC$SYSTEM_INCLUDE to be any valid directory or list of directories you choose.

Avoid defining DECC$SYSTEM_INCLUDE to be a rooted directory or subdirectory of the following form:

`DBA0:[dir-name.]`

When defining DECC$SYSTEM_INCLUDE, use complete directory specifications.

If DECC$SYSTEM_INCLUDE translates to a directory or a search list of directories, and if the compiler cannot locate the specified file, the compiler generates an error message. If DECC$SYSTEM_INCLUDE is undefined, the compiler then searches the DECC$LIBRARY_INCLUDE or SYS$LIBRARY directory for the specified file; if the file cannot be found, the compiler generates an error message. For more information about search lists, see the DCL command DEFINE in the OpenVMS DCL Dictionary.

Note The purpose of DECC$LIBRARY_INCLUDE is to identify an alternative location for all header files normally provided by the compiler installation. Therefore, if this logical is defined, the compiler does not search the SYS$COMMON directories, the SYS$LIBRARY text libraries, or header files it would normally search. The purpose of DECC$SYSTEM_INCLUDE is to define the order for searching directories of plain-text files for the angle-bracketed form of `#include` . Defining this logical does not suppress the search of the SYS$LIBRARY text libraries where the compiler-supplied header files normally reside.

When porting programs to the OpenVMS environment, your programs may contain `#include` directives of the following form:

`#include <sys/file.h>`

The Compaq C compiler translates this line, common in programs that run on UNIX systems, to the following UNIX style file specification:

`/sys/file.h`

The compiler then translates the UNIX style file specification to the OpenVMS file specification as follows:

`SYS:FILE.H`

If you port programs containing such directives, define the SYS logical to be the proper name of the OpenVMS directory containing the files to be included.

Another way to use UNIX style directories is to specify them on the /INCLUDE_DIRECTORY command-line qualifier. They must contain a "/" character and must, therefore, be in quotation marks.

## 5.2.2 Inclusion Using Quotation Marks

The second form of the `#include` preprocessor directive uses quotation marks to delimit the file specification:

`#include "file-spec"`

The file-spec is a valid OpenVMS or UNIX style file specification.

For this form of file inclusion, the compiler searches directories in the following order for the file to be included:

1. One of the following directories:
   - If /NESTED_INCLUDE_DIRECTORY=INCLUDE_FILE (the default) is specified, the directory where the immediately containing include file is located (that is, the directory containing the file in which the `#include` directive occurred).
   - If /NESTED_INCLUDE_DIRECTORY=PRIMARY_FILE is specified, the directory containing the top-level source file (that is, the directory containing the .C file being compiled, which is not necessarily the current default directory). This is most similar to the behavior of the VAX C compiler.
   - If /NESTED_INCLUDE_DIRECTORY=NONE is specified, then skip this step and begin at step 2.
2. Any directories specified with the /INCLUDE_DIRECTORY qualifier.
3. The directory or search list of directories specified in the logical name DECC$USER_INCLUDE, if DECC$USER_INCLUDE is defined.
4. If the file is still not found, the steps for angle-bracketed files are followed.

Note that when /NESTED_INCLUDE_DIRECTORY=PRIMARY_FILE is specified, the directory containing the top-level source file is not necessarily the current RMS default device and directory.

For example, given the current directory, DBA0:[CURRENT], and the following CC command line, the compiler searches DBA0:[OTHERDIR] for any included files delimited by quotation marks, even though the current RMS default is the directory, DBA0:[CURRENT]:

    $ CC  DBA0:[OTHERDIR]EXAMPLE.C[Return]

If the compiler cannot locate the specified file, it searches any directories specified by the /INCLUDE_DIRECTORY qualifier.

If the compiler still cannot locate the specified file, it translates the logical name DECC$USER_INCLUDE. If DECC$USER_INCLUDE translates to a valid directory specification or a search list of directories, the compiler searches that directory or directories for the specified file. Before each compilation of your program, you can redefine DECC$USER_INCLUDE to be any valid directory or list of directories you choose.

As with DECC$SYSTEM_INCLUDE, do not define DECC$USER_INCLUDE to be a rooted directory or subdirectory. Use complete directory specifications when defining DECC$USER_INCLUDE.

If you defined DECC$USER_INCLUDE, and the compiler cannot locate the specified file in that directory or search list of directories, the file-spec is treated as if it were enclosed in angle brackets instead of quotation marks.

## 5.2.3 Inclusion of Text Modules

The third form of the `#include` preprocessor directive is used for including module names:

`#include module-name`

The module-name is the name of a module in a text library.

This method of inclusion is not portable unless module-name is a macro that expands to either the angle-bracket or quoted form. This module-name syntax is provided for compatibility with VAX C and other OpenVMS compilers only, and should generally be avoided.

Compaq C text libraries on OpenVMS systems are specified and searched in the following manner:

1. A text library can be created with the LIBRARY command and specified with the /LIBRARY qualifier on the CC command line.
2. If you compile more than one compilation unit using a single CC command, you must specify the library within each of the compilation units, if needed. For example:

       $ CC sourcea+mylib/LIBRARY, sourceb+mylib/LIBRARY

3. If you specify more than one library to the Compaq C compiler, and if the `#include` directives are not nested (see the note in Section 5.2.2), then the libraries are searched in the specified order each time an `#include` directive is encountered. Consider the following example:

       $ CC sourcea+mylib/LIBRARY+yourlib/LIBRARY

   In this example, the compiler searches for modules referenced in `#include` directives first in MYLIB.TLB and then in YOURLIB.TLB.
4. If no library is specified on the CC command line, or if the specified module cannot be found in any of the specified libraries, the following actions are taken:
   - If you defined an equivalence name for DECC$TEXT_LIBRARY that names a text library, that library is searched.
   - The compiler searches for any remaining unresolved module names in the following location, which contains the Compaq C RTL header files:

     > SYS$LIBRARY:DECC$RTLDEF.TLB

     For OpenVMS Alpha systems and for OpenVMS VAX systems Version 7.1 and higher, the compiler then searches the following location, which contains the STARLET header files:

     > SYS$LIBRARY:SYS$STARLET_C.TLB

## 5.2.4 Macro Substitution in #include Directives

Compaq C allows macro substitution within the `#include` preprocessor directive.

For example, if you want to include a file name, you can use the following two directives:

    #define  macro1  "file.ext"
    #include macro1

If you use defined macros in `#include` directives, the macros must evaluate to one of the three following acceptable `#include` file specifications or the use generates an error message:

`<file-spec> "file-spec" module-name`

# 5.3 Changing the Default Object Module Name and Identification (#module)

The `#module` directive is retained for compatibility with VAX C and is supported only when running Compaq C in VAX C mode (/STANDARD=VAXC). See Section 5.4.13 for information on using the ANSI C equivalent `#pragma module` directive.

# 5.4 Implementation-Specific Preprocessor Directive (#pragma)

The `#pragma` directive is a standard method for implementing features that vary from one compiler to the next. This section describes the implementation-specific pragmas that are available on the Compaq C compiler for OpenVMS systems. Pragmas supported by all implementations of Compaq C are described in the Compaq C Language Reference Manual.

Some `#pragma` directives are subject to macro expansion in the preprocessor before being translated. A macro reference can occur anywhere after the keyword `pragma` . The following example demonstrates this feature using the `#pragma inline` directive:

    #define opt inline
    #define f func
    #pragma opt(f)

The `#pragma` directive becomes `#pragma inline (func)` after both macros are expanded.

The following pragmas are subject to macro expansion:

    builtins            inline                 linkage       standard
    dictionary          noinline               module        nostandard
    extern_model        member_alignment       message       use_linkage
    extern_prefix       nomember_alignment

Note To provide macro-expansion support to those pragmas not listed above, all pragmas (including those that are already specified as undergoing macro expansion) have an alternative pragma-name `_m` version, which makes the pragma subject to macro expansion. For example, `#pragma assert` is not subject to macro expansion, but `#pragma assert_m` is.

The following sections describe the `#pragma` directives.

## 5.4.1 #pragma assert Directive

The `#pragma assert` directive lets you specify assertions that the compiler can make about a program to generate more efficient code. The pragma 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.

The `#pragma assert` directive has the following formats:

`#pragma assert func_attrs(identifier-list)function-assertions (ALPHA ONLY) #pragma assert global_status_variable(variable-list) (ALPHA ONLY) #pragma assert non_zero(constant-expression) string-literal`

### 5.4.1.1 #pragma assert func_attrs (ALPHA ONLY)

Use this form of the pragma to make assertions about a function's attributes.

The identifier-list is a list of function identifiers about which the compiler can make assumptions. If more than one identifier is specified, separate them by commas.

The function-assertions specify the assertions to the compiler about the functions. Specify one or more of the following, separating multiple assertions with whitespace:

> `noreturn`
> `nocalls_back`
> `nostate`
> `noeffects`
> `file_scope_vars(option)`
> `format (style, format-index, first-to-check-index)`

`noreturn` asserts to the compiler that any call to the routine will never return.

`nocalls_back` asserts to the compiler that no routine in the source module will be called before control is returned from this function.

`nostate` asserts to the compiler that the value returned by the function and any side-effects the function might have are determined only by the function's arguments. If a function is marked as having both noeffects and nostate, the compiler can eliminate redundant calls to the function.

`noeffects` asserts to the compiler that any call to this function will have no effect except to set the return value of the function. If the compiler determines that the return value from a function call is never used, it can remove the call.

`file_scope_vars` (option) asserts to the compiler how a function will access variables declared at file scope (with either internal or external linkage).

The option is one of the following:

> `none` - The function will not read nor write to any file-scope variables except those whose type is `volatile` or those listed in a `#pragma assert global_status_variable` .
> `noreads` - The function will not read any file-scope variables except those whose type is `volatile` or those listed in a `#pragma assert global_status_variable` .
> `nowrites` - The function will not write to any file-scope variables except those whose type is `volatile` or those listed in a `#pragma assert global_status_variable` .

`format (style, format-index, first-to-check-index)` asserts to the compiler that this function takes `printf` - or `scanf` -style arguments to be type-checked against a format string. Specify the parameters as follows:

> style - `printf` or `scanf` .
> This determines how the format string is interpreted.
> format-index - {1|2|3|...}
> This specifies which argument is the format-string argument (starting from 1).
> first-to-check-index - {0|1|2|...}
> This is the number of the first argument to check against the format string. For functions where the arguments are not available to be checked (such as `vprintf` ), specify the third parameter as 0. In this case, the compiler only checks the format string for consistency.

The following declaration causes the compiler to check the arguments in calls to `your_printf` for consistency with the `printf` -style format-string argument `your_format` :

    extern int
    your_printf (void *your_object, const char *your_format, ...);
    #pragma assert func_attrs(your_printf) format (printf, 2, 3)

The format string ( `your_format` ) is the second argument of the function `your_printf` , and the arguments to check start with the third argument, so the correct parameter values for format-index and first-to-check-index are 2 and 3, respectively.

The `format` attribute of `#pragma assert func_attrs` allows you to identify your own functions that take format strings as arguments, so that the compiler can check the calls to these functions for errors. The compiler checks formats for the library functions `printf` , `fprintf` , `sprintf` , `snprintf` , `scanf` , `fscanf` , and `sscanf` whenever these functions are enabled as intrinsics (the default). You can use the `format` attribute to assert that the compiler should check the formats of these functions when they are not enabled as intrinsics.

Previous | Next | Contents | Index

privacy and legal statement