Jump to 
content
HP.com Home Products and Services Support and Drivers Solutions How to Buy
»  Contact HP

 

HP C

HP C
User's Guide for OpenVMS Systems


Previous Contents Index

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.

HP 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 HP 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 HP C RTL header files:
      • SYS$LIBRARY:DECC$RTLDEF.TLB

      For OpenVMS 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

HP 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 HP C in VAX C mode (/STANDARD=VAXC). See Section 5.4.15 for information on using the standard 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 HP C compiler for OpenVMS systems. Pragmas supported by all implementations of HP C are described in the HP 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



An _nm suffix can be appended to any of the above-listed macros to prevent macro expansion. For example, to prevent macro expansion on #pragma inline, specify it as #pragma inline_nm.

Also, 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. Another example: #pragma module and #pragma module_m are equivalent and both subject to macro expansion.

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 

#pragma assert global_status_variable(variable-list)
#pragma assert non_zero(constant-expression) string-literal

5.4.1.1 #pragma assert func_attrs

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 white space:

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

5.4.1.2 #pragma assert global_status_variable

Use this form of the pragma to specify variables that are to be considered global status variables, which are exempt from any assertions given to functions by #pragma assert func_attrs file_scope_vars directives.

The variable-list is a list of variables.

5.4.1.3 Usage Notes

The following notes apply to the #pragma assert func_attrs and #pragma assert global_status_variable forms of the #pragma assert directive:

  • The #pragma assert directive is not subject to macro replacement.
  • The variables in the variable-list and the identifiers in the identifier-list must have declarations that are visible at the point of the #pragma assert directive.
  • The #pragma assert directive must appear at file scope.
  • A function can appear on more than one #pragma assert func_attrs directive as long as each directive specifies a different assertion about the function. For example, the following is valid:


    #pragma assert func_attrs(a) nocalls_back 
    #pragma assert func_attrs(a) file_scope_vars(noreads) 
    

    But the following is not valid:


    #pragma assert func_attrs(a) file_scope_vars(noreads) 
    #pragma assert func_attrs(a) file_scope_vars(nowrites) 
    

5.4.1.4 #pragma assert non_zero

This form of the #pragma assert directive is supported on both VAX and Alpha platforms.

When the compiler encounters this directive, it evaluates the constant-expression. If the expression is zero, the compiler generates a message that contains both the specified string-literal and the compile-time constant-expression. For example:


#pragma assert non_zero(sizeof(a) == 12) "a is the wrong size" 

In this example, if the compiler determines that sizeof a is not 12, the following diagnostic message is output:


CC-W-ASSERTFAIL, The assertion "(sizeof(a) == 12)" was not true. 
a is the wrong size. 

Unlike the #pragma assert options func_attrs and global_status_variable, #pragma assert non_zero can appear either inside or outside a function body. When used inside a function body, the pragma can appear wherever a statement can appear, but the pragma is not treated as a statement. When used outside a function body, the pragma can appear anywhere a declaration can appear, but the pragma is not treated as a declaration.

Because macro replacement is not performed on #pragma assert, you might need to use the #pragma assert_m directive to obtain the results you want. Consider the following program that verifies both the size of a struct and the offset of one of its elements:


#include <stddef.h> 
typedef struct { 
    int a; 
    int b; 
} s; 
#pragma assert non_zero(sizeof(s) == 8) "sizeof assert failed" 
#pragma assert_m non_zero(offsetof(s,b) == 4) "offsetof assert failed" 

Because offsetof is a macro, the second pragma must be #pragma assert_m so that offsetof will expand correctly.

5.4.2 #pragma builtins Directive

The #pragma builtins directive enables the HP 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 

HP 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", HP C does not support #pragma nobuiltins.

Furthermore, the names of all the built-in functions use a naming convention defined by the C standard to be in a namespace reserved to the C language implementation. (For more details, see the following Note.)

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 HP C implementation relies on the standard 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 HP 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.

5.4.3 #pragma dictionary Directive

The #pragma dictionary directive allows you to extract CDD/Repository data definitions and include these definitions in your program.

The standard-conforming #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 HP C program can reference this definition with the #pragma dictionary directive. If the #pragma dictionary directive is not embedded in a HP 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 HP 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 HP C structure declaration as follows:


struct 
{ 
   int id; 
 
#pragma dictionary "cname_record" 
 
}  customer; 

These lines of code result in the following declaration, which uses cname as an identifier for the embedded structure:


struct 
{ 
   int id; 
   struct 
   { 
      char first [20]; 
      char last [20]; 
   }  cname; 
}  customer; 

If you specify /LIST and either /SHOW=DICTIONARY or /SHOW=ALL in the compilation command line, then the translation of the CDD/Repository record description into HP C is included in the listing file and marked with the letter D in the margin.

For information on HP C support for CDD/Repository data types. see Section C.4.3.


Previous Next Contents Index

Privacy statement Using this site means you accept its terms
© 2007 Hewlett-Packard Development Company, L.P.