[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

5.4.1.2 #pragma assert global_status_variable (ALPHA ONLY)

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 Compaq 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

Compaq 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", Compaq 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.)

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 Compaq 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 Compaq 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 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 Compaq C program can reference this definition with the #pragma dictionary directive. If the #pragma dictionary directive is not embedded in a Compaq 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 Compaq 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 Compaq 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 Compaq C is included in the listing file and marked with the letter D in the margin.

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

5.4.4 #pragma environment Directive

The #pragma environment directive offers a global way to set, save, or restore the states of context pragmas. This directive protects include files from contexts set by encompassing programs, and protects encompassing programs from contexts that could be set in header files that they include.

The #pragma environment directive affects the following context pragmas:

#pragma extern_model
#pragma extern_prefix
#pragma member_alignment
#pragma message
#pragma names
#pragma pointer_size
#pragma required_pointer_size

This pragma has the following syntax:


#pragma environment command_line
#pragma environment header_defaults
#pragma environment restore
#pragma environment save

The command_line keyword sets the states of all the context pragmas as specified on the command line (by default or by explicit use of the /[NO]MEMBER_ALIGNMENT, /[NO]WARNINGS, /EXTERN_MODEL, and /POINTER_SIZE qualifiers). You can use #pragma environment command_line within header files to protect them from any context pragmas that take effect before the header file is included.

The header_defaults keyword sets the states of all the context pragmas to their default values. This is almost equivalent to the situation in which a program with no command-line options and no pragmas is compiled, except that this pragma sets the pragma message state to #pragma nostandard , as is appropriate for header files.

The save keyword saves the current state of every pragma that has an associated context.

The restore keyword restores the current state of every pragma that has an associated context.

Without requiring further changes to the source code, you can use #pragma environment to protect header files from things like language extensions and enhancements that might introduce additional contexts.

A header file can selectively inherit the state of a pragma from the including file and then use additional pragmas as needed to set the compilation to non-default states. For example:


#ifdef __pragma_environment
#pragma __environment save  (1)
#pragma __environment header_defaults (2)
#pragma member_alignment restore (3)
#pragma member_alignment save (4)
#endif
.
.  /* contents of header file */
.
#ifdef __pragma_environment
#pragma __environment restore
#endif

In this example:

  1. Saves the state of all context pragmas
  2. Sets the default compilation environment
  3. Pops the member alignment context from the #pragma member_alignment stack that was pushed by #pragma __environment save [restoring the member alignment context to its pre-existing state]
  4. Pushes the member alignment context back onto the stack so that the #pragma __environment restore can pop the entry off.

Thus, the header file is protected from all pragmas, except for the member alignment context that the header file was meant to inherit.

5.4.5 #pragma extern_model Directive

The #pragma extern_model directive controls how the compiler interprets objects that have external linkage. With this pragma, you can choose one of the following global symbol models to be used for external objects:

  • Common block model
    All declarations are definitions, and the linker combines all definitions with the same name into one definition. This is the model traditionally used for extern data by VAX C on OpenVMS VAX systems.
  • Relaxed ref/def model
    Some declarations are references and some are definitions. Multiple uninitialized definitions for the same object are allowed and resolved into one by the linker. However, a reference requires that at least one definition exists. This model is used by C compilers on UNIX systems.
  • Strict ref/def model
    Some declarations are references and some are definitions. There must be exactly one definition in the program for any symbol referenced. This model is the only one guaranteed to be acceptable to all ANSI C implementations. It is also the one used by VAX C for globaldef and globalref data. The relaxed ref/def model is the default model on Compaq C.
  • Globalvalue model
    This is like the strict ref/def model, except that these global objects have no storage; they are, instead, link-time constant values. This model is used by VAX C globalvalue symbols.

After a global symbol model is selected with the extern_model pragma, all subsequent declarations of objects having external storage class are treated according to the specified model until another extern_model pragma is specified.

For example, consider the following pragma:


#pragma extern_model strict_refdef

After this pragma is specified, the following file-level declarations are treated as declaring global symbols according to the strict ref/def model:


int x = 0;
extern int y;

Regardless of the external model, the compiler uses ANSI C rules to determine if a declaration is a definition or a reference, although that distinction is not used in the common block model. An external definition is a file-level declaration that has no storage-class keyword, or that contains the extern storage-class keyword, and is also initialized. A reference is a declaration that uses the extern storage-class keyword and is not initialized. In the previous example, the declaration of x is a global definition and the declaration of y is a global reference.

The extern_model pragma does not affect the processing of declarations that contain the VAX C keywords globaldef , globalref , or globalvalue .

Compaq C also supports the command-line qualifiers /EXTERN_MODEL and /SHARE_GLOBALS to set the external model when the program starts to compile. Pragmas in the program being compiled supersede the command-line qualifier.

A stack of the compiler's external model state is kept so that #pragma extern_model can be used transparently in header files and in small regions of program text. See Sections 5.4.5.6 and 5.4.5.7 for more information.

The compiler issues an error message if the same object has two different external models specified in the same compilation unit, as in the following example:


#pragma extern_model common_block
int i = 0;
#pragma extern_model strict_refdef
extern int i;

Notes

  • The global symbols and psect names generated under the control of this pragma obey the case-folding rules of the /NAME qualifier. This behavior is consistent with VAX C.
  • While #pragma extern_model can be used to allocate several variables in the same psect, the placement of variables relative to each other within that psect cannot be controlled: the compiler does not necessarily allocate distinct variables to memory locations according to the order of appearance in the source code.

    Furthermore, the order of allocation can change as a result of seemingly unrelated changes to the source code, command-line options, or from one version of the compiler to the next; it is essentially unpredictable. The only way to control the placement of variables relative to each other is to make them members of the same struct type.

See Section 5.4.5.8 to determine what combinations of external models are compatible for successfully compiling and linking your programs.

The following sections describe the various forms of the #pragma extern_model directive.

5.4.5.1 Syntax

The #pragma extern_model directive has the following syntax:


#pragma extern_model model_spec [attr[,attr]...]

model_spec is one of the following:

common_block
relaxed_refdef
strict_refdef "name"
strict_refdef (No attr specifications allowed)
globalvalue (No attr specifications allowed)

[attr[,attr]...] are optional psect attribute specifications chosen from the following (at most one from each line):

gbl lcl (Not allowed with relaxed_refdef )
shr noshr
wrt nowrt
pic nopic (Not meaningful for Alpha)
ovr con
rel abs
exe noexe
vec novec
For OpenVMS Alpha systems: 0 byte 1 word 2 long 3 quad 4 octa 5 6 7 8 9 10 11 12 13 14 15 16 page
For OpenVMS VAX systems: 2 long 3 quad 4 octa 9 page

The last line of attributes are numeric alignment values. When a numeric alignment value is specified on a section, the section is given an alignment of two raised to that power.

On OpenVMS Alpha systems, the strict_refdef "name" extern_model can also take the following psect attribute specifications:

  • noreorder --- causes variables in the section to be allocated in the order they are defined.
  • natalgn --- has no effect on OpenVMS systems.
    It does, however, change the behavior on Tru64 UNIX systems: when specified, natalgn causes the global variables defined within the section to be allocated on their natural boundary. Currently, all global variables on Tru64 UNIX systems are allocated on a quadword boundary. When the natalgn attribute is specified, the compiler instead allocates the variable on an alignment that is natural for its type ( char s on byte boundaries, int s on longword boundaries, and so on).
    Specifying the natalgn attribute also enables the noreorder attribute.

    Note

    Use of the natalgn attribute can cause a program to violate the Tru64 UNIX Calling Standard. The calling standard states that all global variables must be aligned on a quadword boundary. Therefore, variables declared in a natalgn section should only be referenced in the module that defines them.

See Table 4-3 for a description of the other attributes. See the OpenVMS Linker Utility Manual for more complete information on each.

The default attributes are: noshr , rel , noexe , novec , nopic .

For strict_refdef , the default is con . For common_block and relaxed_refdef , the default is ovr .

The default for wrt / nowrt is determined by the first variable placed in the psect. If the variable has the const type qualifier (or the readonly modifier), the psect is set to nowrt . Otherwise, it is set to wrt .

Restrictions on Setting Psect Attributes

Be aware of the following restriction on setting psect attributes.

The #pragma extern_model directive does not set psect attributes for variables declared as tentative definitions in the relaxed_refdef model . A tentative definition is one that does not contain an initializer. For example, consider the following code:


#pragma extern_model relaxed_refdef long
int a;
int b = 6;
#pragma extern_model common_block long
int c;

Psect A is given octaword alignment (the default) because a is a tentative definition. Psect B is correctly given longword alignment because it is initialized and is, therefore, not a tentative definition. Psect C is also given longword alignment because it is declared in an extern_model other than relaxed_refdef .

Note

The psect attributes are normally used by system programmers who need to perform declarations normally done in macro. Most of these attributes are not needed in normal C programs. Also, notice that the setting of attributes is supported only through the #pragma mechanism, and not through the /EXTERN_MODEL command-line qualifier.


Previous Next Contents Index