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.
The #pragma [no]builtins directive is provided for VAX C compatibility. It disables or enables access to the DEC C built- in functions. When enabled through #pragma builtins, these functions do not result in a reference to a function in the run-time library or in your program. Instead, the compiler generates the machine instructions necessary to carry out the function directly at the call site. (For information on available built-in functions, see Section 6.2.)
The #pragma [no]builtins directive has the following formats:
#pragma builtins #pragma nobuiltins
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:
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 DEC C is included in the listing file and marked with the letter D in the margin.
For information on DEC C support for CDD/Repository data types. see Section C.4.3.
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:
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:
Thus, the header file is protected from all pragmas, except for the member alignment context that the header file was meant to inherit.
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:
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.
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.
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 DEC C.
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.
DEC 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.4.6 and 5.4.4.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;
Note that 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.
See Section 5.4.4.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.
The #pragma extern_model directive has the following syntax:
#pragma extern_model model_spec [attr[,attr]...]
model_spec is one of the following:
[attr[,attr]...] are optional psect attribute specifications chosen from the following (at most one from each line):
See Table 4-4 for a description of these 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 restrictions on setting psect attributes:
#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.
This pragma sets the compiler's model of external data to the common block model, which is the one used by VAX C.
The #pragma extern_model common_block directive has the following format:
#pragma extern_model common_block [attr[,attr]...]
In this model, every declaration of an object with the extern storage class causes a global overlaid psect to be created. Both ANSI C definition declarations and reference declarations create the same object file records.
The psect has the same name as the object itself. There is no global symbol in addition to the psect name.
The object file records generated are the same as those generated by VAX C for extern objects.
See Section 4.8 for a description of how definitions using each external model are interpreted, what psect they would reside in, and what psect attributes are assigned. Also note the effect of the const type specifier for these definitions.
This pragma sets the compiler's model of external data to the relaxed ref/def model, which is the one used by pcc on UNIX systems.
The #pragma extern_model relaxed_refdef directive has the following format:
#pragma extern_model relaxed_refdef [attr[,attr]...]
Be aware that an attr keyword of gbl or lcl is not allowed on the relaxed_refdef model.
With this model, three different types of object-file records can be produced, depending on the declaration of the object:
globaldef "FOO" int FOO = 1;
See Section 4.8 for a description of how definitions using each external model are interpreted, what psect they would reside in, and what psect attributes are assigned. Also note the effect of the const type specifier for these definitions.
This pragma is the preferred alternative to the nonstandard storage- class keywords globaldef and globalref.
This pragma sets the compiler's model of external data to the strict ref/def model. Use this model for a program that is to be an ANSI C strictly conforming program.
The #pragma extern_model strict_refdef directive has the following formats:
#pragma extern_model strict_refdef #pragma extern_model strict_refdef "name" [attr[,attr]...]
The name in quotes, if specified, is the name of the psect for any definitions.
Note that attr keywords cannot be specified for the strict_ refdef model unless a name is given for the psect.
This model provides two different cases:
See Section 4.8 for a description of how definitions using each external model are interpreted, what psect they would reside in, and what psect attributes are assigned. Also note the effect of the const type specifier for these definitions.
This pragma sets the compiler's external model to the globalvalue model, and is the preferred alternative to the nonstandard storage- class keyword globalvalue.
This pragma has the following format:
#pragma extern_model globalvalue
Notice that this model does not accept attr keywords.
This model provides two different cases:
This pragma pushes the current external model of the compiler onto a stack. The stack records all information associated with the external model, including the shr/noshr state and any quoted psect name.
This pragma has the following format:
#pragma extern_model save
The number of entries allowed in the #pragma extern_model stack is limited only by the amount of memory available to the compiler.
This pragma pops the external model stack of the compiler. The external model is set to the state popped off the stack. The stack records all information associated with the external model, including the shr/noshr state and any quoted psect name. This pragma has the following format:
#pragma extern_model restore
On an attempt to pop an empty stack, a warning message is issued and the compiler's external model is not changed.
Using different DEC C external models can introduce mutually incompatible object files. An object file compiled with one extern model may not link against an object file compiled with a different model.
Table 5-1 compares what happens when a reference or definition in an object file compiled with one external model is linked against a reference or definition in an object file compiled with a different external model. Note that the table is symmetric about the diagonal. For example, to look up what happens when you mix a relaxed_refdef reference with a strict_refdef definition, you can locate either the relaxed_refdef reference row and the strict_refdef definition column or the relaxed_refdef reference column and the strict_refdef definition row.
Table 5-1 contains no entries for mixing globalvalue symbols with other external models because globalvalue symbols are used only in special cases; they are not used as a general-purpose external model. For the other external models, there is a row and column for every different case. The common_ block model only has one case because all symbols are definitions in that model; the relaxed_refdef model has three cases because it distinguishes between references, uninitialized definitions, and initialized definitions.
common_block def | relaxed_ refdef ref | relaxed_refdef def | relaxed_ refdef initialized def | strict_refdef ref | strict_refdef def | |
---|---|---|---|---|---|---|
common_block def | Works | Fails | Works | Works | Fails | Fails |
relaxed_refdef ref | Fails | Works | Works | Works | Works | Works |
relaxed_refdef uninitialized def | Works | Works | Works | Works | Works | Works |
relaxed_refdef initialized def | Works | Works | Works | Multi | Works | Multi |
strict_refdef ref | Fails | Works | Works | Works | Works | Works |
strict_ refdef def | Fails | Works | Works | Multi | Works | Multi |
Notes
ref means reference; def means definition. In the common_block model, all external symbols are considered to be defs. A ref works with a ref if they both refer to the same thing. A def works with a ref if the def fulfills the ref. A def works with a def if they are combined into one by the linker. Multi means that the linker issues a multiply defined symbol error. This indicates a user error, not a mismatch between external models. |
As Table 5-1 shows, the common_block model mixes poorly with the strict_refdef model, but the relaxed_ refdef model works well with the common_block model and the strict_ refdef model. The relaxed_refdef model fails only when a relaxed_ refdef reference is linked against a common_block definition.
The fact that the external models are not all compatible with each other can be an issue for providers of general-purpose object libraries. One goal for such a library should be to work when linked with client code compiled with any of the external models. Otherwise, the provider of the object library might be forced to provide one copy of the library compiled with /EXTERN_MODEL=COMMON_ BLOCK, another compiled with /EXTERN_MODEL=STRICT_REFDEF, and another compiled with /EXTERN_MODEL=RELAXED_REFDEF to let anyone link with the library.
The best way to accomplish the goal of allowing an object library to be linked with any code regardless of the external model used is to provide header files that describe the interface to the object library. The header files can declare the global variables used by the object library after using #pragma extern_model to set the external model to the one used by the library. Programmers who want to use the library could then include these header files to get the required declarations. In order to avoid altering the external model used by the including program, header files should start with a #pragma extern_model save directive and end with a #pragma extern_ model restore directive. The DEC C RTL uses this approach.
If header files are not provided, an object library should use the relaxed_refdef external model since it will link successfully with either common_block compiled code or strict_refdef compiled code. The only restriction is that the library must not reference an external symbol that is not defined in the library but is defined only in the user program. This avoids the common_block case that fails. Note that the relaxed_refdef model allows both the library and the user code to contain definitions for any symbol, as long as both do not attempt to initialize the symbol.
Example 5-1 shows the use of #pragma extern_model in a sample module. Assume that the module is compiled with the /EXTERN_MODEL=COMMON and /SHARE_GLOBALS qualifiers.
#pragma extern_model save globaldef "BAR1" int FOO1; /* strict_refdef shr def */ extern int com1; /* common_block shr def */ int com2; /* common_block shr def */ #pragma extern_model common_block noshr globaldef "BAR2" int FOO2; /* strict_refdef shr def */ extern int com3 = 23; /* common_block noshr def */ #pragma extern_model globalvalue int gv1; /* globalvalue def */ extern int gv2; /* globalvalue ref */ int gv3 = 5; /* globalvalue def */ extern int gv4 = 42; /* globalvalue def */ #pragma extern_model strict_refdef "BAR1" shr int FOO1A; /* strict_refdef shr def */ extern int FOO1B; /* strict_refdef ref */ globaldef "BAR3" noshare int foo3; #pragma extern_model relaxed_refdef int rrd1; /* relaxed_refdef noshr def */ extern rrd2; /* relaxed_refdef ref */ #pragma extern_model restore int com4; /* common_block shr def */
Key to Example 5-1:
The #pragma extern_prefix directive controls the compiler's synthesis of external names, which the linker uses to resolve external name requests.
When you specify #pragma extern_prefix
with a string
argument, the DEC C++ compiler attaches the string to the beginning
of all external names produced by the declarations that follow the
pragma specification.
This pragma is useful for creating libraries where the facility code can be attached to the external names in the library.
The #pragma intrinsic directive has the following format:
#pragma extern_prefix "string" #pragma extern_prefix save #pragma extern_prefix restore
The quoted "string" is attached to external names in the declarations that follow the pragma specification.
The save and restore keywords can be used to save the current pragma prefix string and to restore the previously saved pragma prefix string, respectively.
The default external prefix, when none has been specified by a pragma, is the null string.
The recommended use is as follows:
When an extern_prefix is in effect and you are using #include to include header files, but do not want the extern_prefix to apply to extern declarations in the header files, use the following code sequence:
Otherwise, external prefix is attached to the beginning of external identifiers for definitions in the included files.
All external names prefixed with a nonnull string using #pragma extern_prefix are converted to uppercase letters regardless of the setting of the /NAMES qualifier.
The DEC C compiler treats #pragma extern_prefix independently of the /PREFIX_LIBRARY_ENTRIES qualifier. The /PREFIX_LIBRARY_ENTRIES qualifier affects only ANSI C and DEC C Run-Time Library (RTL) entries; the extern_prefix pragma affects external identifiers for any externally visible name that is explicitly declared.
Function inlining is the inline expansion of function calls; it replaces the function call with the function code itself. Inline expansion of functions reduces execution time by eliminating function-call overhead and allowing the compiler's general optimization methods to apply across the expanded code. Compared with the use of function-like macros, function inlining has the following advantages:
Also, the semantics are exactly the same as if inline expansion had not occurred. You cannot get this behavior using macros.
Use the following preprocessor directives to control function inlining:
#pragma inline ( id, . . . )
#pragma noinline ( id, . . . )
The id is a function identifier.
If a function is named in an inline
directive, calls to
that function will be expanded as inline code, if possible.
If a function is named in a noinline
directive, calls
to that function will not be expanded as inline code.
If a function is named in both an inline
and a
noinline
directive, an error message is issued.
For calls to functions named in neither an inline
nor a noinline
directive, DEC C expands the function
as inline code whenever appropriate as determined by a platform-
specific algorithm.
Use of the #pragma inline
directive causes inline
expansion regardless of the size or number of times the specified
functions are called.
In the following example of function inlining, the functions
push
and pop
are expanded inline
throughout the module in which the #pragma inline
appears:
void push(int); int pop(void); #pragma inline(push, pop) int stack[100]; int *stackp = &stack; void push(int x) { if (stackp == &stack) *stackp = x; else *stackp++ = x; } int pop() { return *stackp--; } main() { push(1); printf("The top of stack is now %d \n",pop()); }
By default, DEC C for OpenVMS Systems attempts to provide inline expansion for all functions, and uses the following function characteristics to determine if it can provide inline expansion:
If a function is to be expanded inline, you must place the function definition in the same module as the function call. The definition can appear either before or after the function call.
The #pragma intrinsic preprocessor directive specifies that calls to the specified functions are intrinsic (UNIX equivalent to built-in function on OpenVMS systems).
The #pragma intrinsic directive has the following format:
#pragma intrinsic (function1[,function2, . . . ])
The following functions have intrinsic forms:
asm fasm dasm
For a description of these asm intrinsic functions, see Section 6.2.1.2.
The #pragma linkage preprocessor directive allows you to specify special linkage types for function calls. This pragma is used with the #pragma use_linkage directive, described in Section 5.4.16, to associate a previously defined special linkage with a function.
The #pragma linkage directive has the following format:
#pragma linkage linkage-name = (characteristics)
The linkage-name is the name to be given to the linkage type being defined. It has the form of a C identifier. Linkage types have their own name space, so their names will not conflict with other identifiers or keywords in the compilation unit.
The characteristics specify information about where parameters will be passed, where the results of the function are to be received, and what registers are modified by the function call. Specify these characteristics as a parenthesized list of comma-separated items of the following forms:
parameters (register-list) result (simple-register-list) preserved (simple-register-list) nopreserve (simple-register-list) notused (simple-register-list) notneeded (ai, lp)
You can supply the parameters, result, preserved, nopreserve, notused, and notneeded keywords in any order.
A simple-register-list is a comma-separated list of register names, either Rn or Fn, where n is a valid register number. A register-list is similar to a simple-register- list except that it can contain parenthesized sublists.
Valid registers for the preserved, nopreserve, and notused options include general-purpose registers R0 through R30, and floating- point registers F0 through F30. Valid registers for the result and parameters options include general-purpose registers R0 through R25 and floating-point registers F0 through F30.
For example, the following characteristics specify a simple-register-list containing two elements, registers F3 and F4; and a register-list containing two elements, the register R0 and a sublist containing the registers F0 and F1:
nopreserve(f3, f4) parameters(r0, (f0, f1))
The following example shows a linkage using such characteristics:
#pragma linkage my_link=(nopreserve(f3,f4), parameters(r0,(f0,f1)), notneeded (ai))
The parenthesized notation in a register-list is used to describe arguments and function return values of type struct, where each member of the struct is passed in a single register. In the following example, sample_linkage specifies two parameters: the first is passed in registers R0, R1, and R2; the second is passed in F1:
struct sample_struct_t { int A, B; short C; } sample_struct; #pragma linkage sample_linkage = (parameters ((r0, r1, r2), f1)) void sub (struct sample_struct_t p1, double p2) { } main() { double d; sub (sample_struct, d); }
You can pass arguments to the parameters of a routine in specific registers. To specify this information, use the following form, where each item in the register-list describes one parameter that is passed to the routine:
parameters (register-list)
You can pass structure arguments by value, with the restriction that each member of the structure is passed in a separate parameter location. Doing so, however, may produce code that is slower because of the large number of registers used. The compiler does not diagnose this condition.
DEC C does not support unions as parameters or function return types for a function with a special linkage.
When a function associated with a linkage type is declared or defined, the compiler checks that the size of any declared parameters is compatible with the number of registers specified for the corresponding parameter in the linkage definition.
The compiler needs to know the registers that will be used to return the value for the function. To specify this information use the following form, where the register-list must contain only a single register, or a parenthesized group of registers if the routine returns a struct:
result (register-list)
If a function does not return a value (that is, the function has a return type of void), then do not specify result as part of the linkage.
The compiler needs to know which registers are used by the function and which are not, and of those used, whether or not they are preserved across the function call. To specify this information, use the following forms:
preserved (register-list) nopreserve (register-list) notused (register-list)
A preserved register contains the same value after a call to the function as it did before the call.
A nopreserve register does not necessarily contain the same value after a call to the function as it did before the call.
A notused register is not used in any way by the called function.
The notneeded characteristic indicates that certain items are not needed by the routines using this linkage. You can specify one or both of the following keywords:
You must determine whether or not it is valid to specify that the ai or lp registers are not needed.
The #pragma linkage directive has the restriction that structures containing nested substructures are not supported as parameters or function return types with special linkages.
By default, DEC C for OpenVMS VAX systems does not align structure members on natural boundaries; they are stored on byte boundaries (with the exception of bit-field members).
By default, DEC C for OpenVMS Alpha systems does align structure members on natural boundaries.
The #pragma member_alignment preprocessor directive can be used to force natural-boundary alignment of structure members. The #pragma nomember_alignment preprocessor directive restores byte-alignment of structure members.
This pragma has the following formats:
#pragma member_alignment #pragma member_alignment save #pragma member_alignment restore #pragma nomember_alignment [base_alignment]
When #pragma member_alignment is used, the compiler aligns structure members on the next boundary appropriate to the type of the member, rather than on the next byte. For example, a long variable is aligned on the next longword boundary; a short variable is aligned on the next word boundary.
Consider the following example:
#pragma nomember_alignment struct x { char c; int b; }; #pragma member_alignment struct y { char c; /*3 bytes of filler follow c */ int b; }; main () { printf( "The sizeof y is: %d\n", sizeof (struct y) ); printf( "The sizeof x is: %d\n", sizeof (struct x) ); }
When this example is executed, it shows the difference between #pragma member_alignment and #pragma nomember_alignment.
Once used, the member_alignment pragma remains in effect until the nomember_alignment pragma is encountered; the reverse is also true.
The optional base_alignment parameter can be used to specify the base-alignment of the structure. Use one of the following keywords for the base_alignment:
The #pragma member_alignment save and #pragma member_alignment restore directives can be used to save the current state of the member_alignment and to restore the previous state, respectively. This feature is necessary for writing header files that require member_alignment or nomember_alignment, or that require inclusion in a member_alignment that is already set.
The #pragma message directive controls the issuance of individual diagnostic messages or groups of messages. Use of this pragma overrides any command-line options that may affect the issuance of messages.
The #pragma message directive has the following formats:
#pragma message option1 (message-list) #pragma message option2
The parameter option1 must be one of the following keywords:
The message-list can be any one of the following:
%CC-W-GLOBALEXT, a storage class of globaldef, globalref, or globalvalue is a language extension.
Only messages of severity Warning (W) or Information (I) can be disabled. If the message has severity of Error (E) or Fatal (F), it is issued regardless of any attempt to disable it.
The parameter option2 must be one of the following keywords:
The save and restore options are useful primarily within header files.
When you compile source files to create an object file, the compiler assigns the first of the file names specified in the compilation unit to the name of the object file. The compiler adds the .OBJ file extension to the object file. Internally, the OpenVMS system (the debugger and the librarian) recognizes the object module by the file name; the compiler also gives the module a version number of 1. For example, given the object file EXAMPLE.OBJ, the debugger recognizes the EXAMPLE object module.
To change the system-recognized module name and version number, use the #pragma module directive. The #pragma module directive is specific to DEC C for OpenVMS systems and is not portable.
You can find the module name and the module version number listed in the compiler listing file and the linker load map.
The #pragma module directive is equivalent to the VAX C compatible #module directive. The #pragma module directive may be used when compiling in any mode. Use #module only when compiling with the /STANDARD=VAXC qualifier.
The #pragma module directive has the following formats:
#pragma module identifier identifier #pragma module identifier string
The first parameter must be a valid DEC C identifier. It specifies the module name to be used by the linker. The second parameter specifies the optional identification that appears on listings and in the object file. It must be either a valid DEC C identifier of 31 characters or less, or a character-string constant of 31 characters or less.
Only one #pragma module directive can be processed per compilation unit, and that directive must appear before any C language text. The #pragma module directive can follow other directives, such as #define, but it must precede any function definitions or external data definitions.
The parameters in a #pragma module directive are subject to text replacement and can, therefore, contain references to identifiers defined in previous #define directives. The replacement occurs before the parameters are processed.
The #pragma pack preprocessor directive specifies the byte boundary for packing members of C structures.
The #pragma pack directive has the following format:
#pragma pack [n]
The n specifies the new alignment restriction in bytes:
1 | align to byte |
2 | align to word |
4 | align to longword |
8 | align to quadword |
16 | align to octaword |
A structure member is aligned to either the alignment specified by #pragma pack or the alignment determined by the size of the structure member, whichever is smaller. For example, a short variable in a structure gets byte-aligned if #pragma pack 1 is specified. If #pragma pack 2, 4, or 8 is specified, the short variable in the structure gets aligned to word.
If #pragma pack is not used or if it is specified without the n, packing defaults to 16 on OpenVMS Alpha systems, and to 1 (byte alignment) on OpenVMS VAX systems.
The #pragma pointer_size preprocessor directive can be used throughout a program to control whether pointers are 32-bit pointers or 64-bit pointers.
This directive has the same effect as the #pragma required_pointer_ size directive, except that #pragma pointer_size is enabled only when the /POINTER_SIZE command-line qualifier is specified. If /POINTER_SIZE is omitted from the command line, #pragma pointer_ size is ignored. (The #pragma required_pointer_size directive always takes effect, whether or not /POINTER_SIZE is specified.)
The #pragma pointer_size directive has the following format:
#pragma pointer_size keyword
The keyword is one of the following:
{short|32} | 32-bit pointer |
{long|64} | 64-bit pointer |
system_default | 32-bit pointers on OpenVMS systems; 64-bit pointers on Digital UNIX systems |
save | Saves the current pointer size |
restore | Restores the current pointer size to its last saved state |
The #pragma required_pointer_size preprocessor directive is intended for use by developers of header files to control the size of pointers within a header file in those cases where the pointers are architecturally required to be a particular size, and must not be altered by the user's use of pointer-size controls.
This directive has the same effect as the #pragma pointer_size directive, except that a #pragma required_pointer_size always takes effect, even if /POINTER_SIZE is omitted from the command line. (The #pragma pointer_size directive is ignored if /POINTER_SIZE is omitted.)
The #pragma required_pointer_size directive has the following format:
#pragma required_pointer_size keyword
The keyword is one of the following:
{short|32} | 32-bit pointer |
{long|64} | 64-bit pointer |
system_default | 32-bit pointers on OpenVMS systems; 64-bit pointers on Digital UNIX systems |
save | Saves the current pointer size |
restore | Restores the current pointer size to its last saved state |
Use the nostandard and standard pragmas together to define regions of source code where portability diagnostics are not to be issued.
This pragma has the following format:
#pragma [no]standard
Use #pragma nostandard to suppress diagnostics about non-ANSI extensions, regardless of the /STANDARD qualifier specified.
Use #pragma standard to direct the compiler to reinstate the setting of the /STANDARD qualifier that was in effect before the last #pragma nostandard was encountered. Every #pragma standard directive must be preceded by a corresponding #pragma nostandard directive.
The following example demonstrates the use of these pragmas:
#include <stdio.h> #pragma nostandard extern noshare FILE *stdin, *stdout, *stderr; #pragma standard
In this example, nostandard prevents the NOSHAREEXT diagnostic from being issued against the noshare storage-class modifier, which is specific to DEC C for OpenVMS systems.
After defining a special linkage using the #pragma linkage directive, described in Section 5.4.8, use the #pragma use_linkage directive to associate the linkage with a function.
This pragma has the following format:
#pragma use_linkage linkage-name (routine1, routine2, ...)
The linkage-name is the name of a linkage previously defined by the #pragma linkage directive.
routine1, routine2, ... are the names of functions that you want associated with the specified linkage.
The #pragma use_linkage directive must appear in the source file before any use or definition of the specified routines. Otherwise, the results are unpredictable.
The following example defines a special linkage and associates it with a routine that takes three integer parameters and returns a single integer result in the same location where the first parameter was passed:
#pragma linkage example_linkage (parameters(r16, r17, r19), result(r16)) #pragma use_linkage example_linkage (sub) int sub (int p1, int p2, short p3); main() { int result; result = sub (1, 2, 3); }
In this example, the result (r16) option indicates that the function result will be returned in R16 rather than the usual location (R0). The parameters option indicates that the three parameters passed to sub should be passed in R16, R17, and R19.