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 DEC 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.
The DEC 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 DEC C Language Reference Manual describes the ANSI-compliant preprocessor directives available with the DEC C compiler. This chapter describes the preprocessor directives that are either specific to DEC C on OpenVMS systems, or that are used in an implementation-specific way:
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 DEC C Language Reference Manual for more information about using preprocessor directives for conditional compilation. For a complete discussion of portability concerns, see the DEC 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 DEC C in VAX C mode (/STANDARD=VAXC). See
Section 5.4.2 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 DEC C functions and macros in the program text.
The #include directive is supported on all DEC 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 DIGITAL 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. DEC 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 DEC C compiler imposes no inherent limitation on the nesting level of inclusion.
OpenVMS and most UNIX style file specifications can be included in DEC 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:
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.
When porting programs to the OpenVMS environment, your programs may contain #include directives of the following form:
#include <sys/file.h> |
The DEC 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:
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.
DEC C text libraries on OpenVMS systems are specified and searched in the following manner:
$ CC sourcea+mylib/LIBRARY, sourceb+mylib/LIBRARY |
$ CC sourcea+mylib/LIBRARY+yourlib/LIBRARY |
DEC 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 DEC C in VAX C mode (/STANDARD=VAXC). See
Section 5.4.12 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 DEC C compiler for OpenVMS systems. Pragmas supported by all implementations of DEC C are described in the DEC C Language Reference Manual.
Note that some #pragma directives are subject to macro expansion. 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 |
The following sections describe the
#pragma
directives.
5.4.1 #pragma builtins Directive
The #pragma builtins directive enables the DEC C built-in functions that directly access processor instructions. This directive is provided for VAX C compatibility.
The #pragma builtins directive has the following format:
#pragma builtins |
DEC 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", DEC 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. (For more details, see the following Note.)
VAX C implemented both #pragma builtins and #pragma nobuiltins . Under #pragma builtins , the names of the built-in functions were given special treatment. Under #pragma nobuiltins , the names of the built-in functions were given no special treatment; as such, a user program was free to declare its own functions or variables with the same names as the builtins and have them behave as if they had ordinary names. The DEC C implementation relies on the ANSI C reserved namespace, which states that any name matching the pattern described above is reserved for the exclusive use of the C implementation (that is, the compiler and RTL), and if a user program tries to declare or define such a name for its own purposes, the behavior is undefined. So in DEC C, the #pragma builtins directive includes a set of declarations that makes the built-in functions operate as documented. But in the absence of the #pragma builtins directive, you cannot declare your own functions with these names. Code that tries to do anything with these names other than use them as documented, and in the presence of #pragma builtins , will likely encounter unexpected problems. |
The #pragma dictionary directive allows you to extract CDD/Repository 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 ( Section 5.1), 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.)
The #pragma dictionary directive has the following format:
#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 a CDD/Repository record, or a macro that expands to the path name of the record.
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 declarator(struct_name) for the outer level of a CDD/Repository structure.
The optional text1_to_char keyword forces the CDD/Repository type "text" to be translated to char , rather than "array of char " if the size is 1. This is the default when null_terminate is not specified.
The optional text1_to_array keyword forces the CDD/Repository 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.
Here's a sample #pragma dictionary directive:
#pragma dictionary "CDD$TOP.personnel.service.salary_record" |
This path name describes all subdirectories, beginning with the root directory (CDD$TOP), that lead to the salary_record data definition.
You can use the logical name CDD$DEFAULT to define a default path name for a dictionary directory. This logical name can specify part of the path name for the dictionary object. For example, you can define CDD$DEFAULT as follows:
$ DEFINE CDD$DEFAULT CDD$TOP.PERSONNEL |
When this definition is in effect, the #pragma dictionary directive can contain the following:
#pragma dictionary "service.salary_record" |
Descriptions of data definitions are entered into the dictionary in a special-purpose language called CDO (Common Dictionary Operator), which replaces the older interface called CDDL (Common Data Dictionary Language).
CDD definitions written in CDDL are included in a dictionary with the CDDL command. For example, you can write the following definition for a structure containing someone's first and last name:
define record cdd$top.doc.cname_record. cname structure. first datatype is text size is 20 characters. last datatype is text size is 20 characters. end cname structure. end cname_record record. |
If a source file named CNAME.DDL needs to use this definition, you can include the definition in the CDD subdirectory named doc by entering the following command:
$ CDDL cname |
After executing this command, a DEC C program can reference this definition with the #pragma dictionary directive. If the #pragma dictionary directive is not embedded in a DEC C structure declaration, then the resulting structure is declared with a tag name corresponding to the name of the CDD/Repository record. Consider the following example:
#pragma dictionary "cdd$top.doc.cname_record" |
This DEC C preprocessor statement results in the following declarations:
struct cname { char first [20]; char last [20]; }; |
You can also embed the #pragma dictionary directive in another DEC C structure declaration as follows:
Previous | Next | Contents | Index |