United States

Compaq C

# Compaq C
User's Guide for OpenVMS Systems

Previous | Contents | Index

### 5.4.5.2 #pragma extern_model common_block

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.

### 5.4.5.3 #pragma extern_model relaxed_refdef

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:

- If the declaration is an ANSI C reference, the same type of object records are produced as VAX C would produce for a `globalref` ; that is, a global symbol reference subrecord.
- If the declaration is an ANSI C definition that is initialized, a psect definition and global symbol definition subrecord are produced. The name of the psect and symbol is the same as the name of the data object. This is equivalent to what VAX C would produce for the declaration. For example:

      globaldef "FOO" int FOO = 1;

- If the declaration is an ANSI C definition that is not initialized, then a conditional global symbol definition subrecord and conditional psect definition subrecord are produced. Except for the conditional aspect and the omission of an initializer, these object records resemble those produced with the `#pragma extern_model common_block` directive.

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.

### 5.4.5.4 #pragma extern_model strict_refdef

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:

- If the declaration is an ANSI C reference, the same type of object records are produced as VAX C would produce for a `globalref` ; that is, a global symbol reference subrecord.
- If the declaration is an ANSI C definition, the same type of object records are produced as VAX C would produce for a `globaldef` ; that is, a global symbol definition subrecord.

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.

Note In VAX C, the `globaldef` and `globalref` keywords interact with `enum` definitions in the following way: If an `enum` variable is declared with the `globaldef` keyword, the `enum` literals of the type of the variable automatically become `globalvalue` constant definitions. If an `enum` variable is declared with the `globalref` keyword, the `enum` literals of the type of the variable automatically become `globalvalue` constant references. This behavior, does not occur with `#pragma extern_model strict_refdef` .

### 5.4.5.5 #pragma extern_model globalvalue

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:

- If the declaration is an ANSI C reference, the same object file records are produced as VAX C would produce for an uninitialized `globalvalue` .
- If the declaration is an ANSI C definition, the same object records are produced as VAX C would produce for an initialized `globalvalue` .

Note Only objects with a type of `integer` , `enum` , or `pointer` can have this external model. If this external model is used and the compiler encounters a declaration of an external object whose type is not one these, an error message is issued.

### 5.4.5.6 #pragma extern_model save

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.

### 5.4.5.7 #pragma extern_model restore

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.

### 5.4.5.8 Effects on the Compaq C Run-Time Library and User Programs

Using different Compaq 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.

Table 5-1 Comparison of Mixing Different extern_models
| 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 Compaq 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.

### 5.4.5.9 Example

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.

Example 5-1 #pragma extern_model Example

    #pragma extern_model save
    (1)globaldef "BAR1" int FOO1;           /* strict_refdef shr def  */
    (2)extern int com1;                     /* common_block shr def   */
    (3)int com2;                            /* common_block shr def   */
    #pragma extern_model common_block noshr
    (4)globaldef "BAR2" int FOO2;           /* strict_refdef shr def  */
    (5)extern int com3 = 23;                /* common_block noshr def */
    #pragma extern_model globalvalue
    (6)int gv1;                             /* globalvalue def        */
    (7)extern int gv2;                      /* globalvalue ref        */
    (8)int gv3 = 5;                         /* globalvalue def        */
    (9)extern int gv4 = 42;                 /* globalvalue def        */
    #pragma extern_model strict_refdef "BAR1" shr
    (10)int FOO1A;                           /* strict_refdef shr def  */
    (11)extern int FOO1B;                    /* strict_refdef ref      */
    (12)globaldef "BAR3" noshare int foo3;
    #pragma extern_model relaxed_refdef
    (13)int rrd1;                            /* relaxed_refdef noshr def */
    (14)extern rrd2;                         /* relaxed_refdef ref     */
    #pragma extern_model restore
    (15)int com4;                            /* common_block shr def   */

Key to Example 5-1:

1. `FOO1` has the `strict_refdef` model with the share attribute (because of /SHARE). It resides in psect `BAR1` .
2. `com1` has the `common_block` model with the share attribute. Like all common_block globals, `com1` is a definition.
3. `com2` has the `common_block` model with the share attribute. Like all common_block globals, `com2` is a definition.
4. `FOO2` has the `strict_refdef` model with the share attribute. The /SHARE qualifier overrides the `noshr` keyword on the preceding `#pragma extern_model` . `FOO2` resides in psect `BAR2` .
5. `com3` has the `common_block` model with the noshare attribute.
6. `gv1` has the `globalvalue` model. It is a definition. Since it lacks an explicit initializer, `gv1` is implicitly initialized to 0. Therefore, it is a `globalvalue` with a link-time value of 0.
7. `gv2` has the `globalvalue` model. It is a reference.
8. `gv3` has the `globalvalue` model. It is a definition with a link-time value of 5.
9. `gv4` has the `globalvalue` model. It is a definition with a link-time value of 42.
10. `FOO1A` has the `strict_refdef` model with the noshare attribute. It is a definition and resides in the psect `BAR1` .
11. `FOO1B` has the `strict_refdef` model and is a reference. Since it is a reference, it will reside in whatever psect is specified by the definition.
12. `foo3` has the `strict_refdef` model with the noshare attribute. It is a definition and resides in the psect `BAR3` .
13. `rrd1` has the `relaxed_refdef` model with the noshare attribute. It is a definition.
14. `rrd2` has the `relaxed_refdef` model and is a reference.
15. `com4` has the `common_block` model with the share attribute, because the preceding line popped the external model back to its command-line state.

## 5.4.6 #pragma extern_prefix Directive

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 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 extern_prefix` directive has the following format:

`#pragma extern_prefix "string" [(id[,id]...)] #pragma extern_prefix save #pragma extern_prefix restore`

The quoted "string" is attached to external names in the declarations that follow the pragma specification.

You can also specify an extern prefix for specific identifiers using the optional list [(id[,id]...)].

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:

> `#pragma extern_prefix save`
> `#pragma extern_prefix "` prefix-to-prepend-to-external-names `"`
> ...some declarations and definitions ...
> `#pragma extern_prefix restore`

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:

> `#pragma extern_prefix save`
> `#pragma extern_prefix ""`
> `#include` ...
> `#pragma extern_prefix restore`

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 Compaq C compiler treats `#pragma extern_prefix` independently of the /PREFIX_LIBRARY_ENTRIES qualifier. The /PREFIX_LIBRARY_ENTRIES qualifier affects only ANSI C and Compaq C Run-Time Library (RTL) entries; the `extern_prefix` pragma affects external identifiers for any externally visible name that is explicitly declared.

Notes The following notes apply when specifying optional identifiers on `#pragma extern_prefix` : For each id there must not be a declaration of that id visible at the point of the pragma, otherwise a warning is issued, and there is no affect on that id. Each id affected by a pragma with a non-empty prefix is expected to be subsequently declared with external linkage in the same compilation unit. The compiler issues a default informational if there is no such declaration made by the end of the compilation. It is perfectly acceptable for the id-list form of the pragma or declarations of the id's listed, to occur within a region of source code controlled by the other form of the pragma. The two forms do not interact; the form with an id list always supersedes the other form. There is no interaction between the save/restore stack and the id lists. If the same id appears in more than one pragma, then a default informational message is issued, unless the prefix on the second pragma is either empty ("") or matches the prefix from the previous pragma. In any case, the behavior is that the last-encountered prefix supersedes all others.

Previous | Next | Contents | Index

privacy and legal statement