[an error occurred while processing this directive]

HP OpenVMS Systems

C Programming Language
Content starts here HP C

HP C
User's Guide for OpenVMS Systems


Previous Contents Index

  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 {NOCRTL|RESTORE_CRTL} (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 NOCRTL and RESTORE_CRTL keywords control whether or not the compiler applies its default RTL prefixing to the names specified in the id-list, which is required for this form of the pragma. The effect of NOCRTL is like that of the EXCEPT=keyword of the /PREFIX_LIBRARY_ENTRIES command-line qualifier. The effect of RESTORE_CRTL is to undo the effect of a #pragma extern_prefix NOCRTL or a /PREFIX=EXCEPT= on the command line.

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.

Notes



The following notes apply when specifying optional identifiers on #pragma extern_prefix :
  • When an id-list follows a quoted "string", then 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.

5.4.7 #pragma function Directive

Specifies that calls to the specified functions are not intrinsic but are, in fact, function calls. This pragma has the opposite effect of #pragma intrinsic .

The #pragma function directive has the following format:


#pragma function (function1[, function2, ...])

5.4.8 #pragma [no]include_directory Directive

The effect of each #pragma include_directory is as if its string argument (including the quotes) were appended to the list of places to search that is given its initial value by the /INCLUDE_DIRECTORY qualifier, except that an empty string is not permitted in the pragma form.

The #pragma include_directory directive has the following format:


#pragma include_directory <string-literal>

This pragma is intended to ease DCL command-line length limitations when porting applications from POSIX-like environments built with makefiles containing long lists of -I options specifying directories to search for headers. Just as long lists of macro definitions specified by the /DEFINE qualifier can be converted to #define directives in a source file, long lists of places to search specified by the /INCLUDE_DIRECTORY qualifier can be converted to #pragma include_directory directives in a source file.

Note that the places to search, as described in the help text for the /INCLUDE_DIRECTORY qualifier, include the use of POSIX-style pathnames, for example "/usr/base" . This form can be very useful when compiling code that contains POSIX-style relative pathnames in #include directives. For example, #include <subdir/foo.h> can be combined with a place to search such as "/usr/base" to form "/usr/base/subdir/foo.h" , which will be translated to the filespec "USR:[BASE.SUBDIR]FOO.H"

This pragma can appear only in the main source file or in the first file specified on the /FIRST_INCLUDE qualifier. Also, it must appear before any #include directives.

5.4.9 #pragma [no]inline Directive

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:

  • Arguments are evaluated only once.
  • The overuse of parentheses is not necessary to avoid problems with precedence.
  • The actual expansion can be controlled from the command line.

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, HP 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, HP 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:

  • Size
  • Number of times the function is called
  • Conformance to the following restrictions:
    • The function does not take the address of a parameter.
    • The function does not use an index expression that is not a compile-time constant in an array that is a field of a struct argument. An argument that is a pointer to a struct is not restricted.
    • The function does not use the varargs or stdarg package to access the function's arguments because they require arguments to be in adjacent memory locations, and inline expansion may violate that requirement.
    • The function does not declare an exception handler.

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.

5.4.10 #pragma intrinsic Directive

The #pragma intrinsic preprocessor directive specifies that calls to the specified functions are intrinsic. An intrinsic function is an apparent function call that could be handled as an actual call to the specified function, or could be handled by the compiler in a different manner. By treating the function as an intrinsic, the compiler can often generate faster code. (Contrast with a built-in function, which is an apparent function call that is never handled as an actual function call. There is never a function with the specified name.)

This pragma has the opposite effect of #pragma function .

The #pragma intrinsic directive has the following format:


#pragma intrinsic (function1[,function2, ...])

Functions that can be handled as intrinsics are:


 
Main Group - Standard C: 
 
 
  abs     atan2   ceilf   cosl    floorl   memset  sinl 
  atan    atan2f  ceill   fabs    labs     sin     strcpy 
  atanf   atan2l  cos     floor   memcpy   sinf    strlen 
  atanl   ceil    cosf    floorf  memmove 
 
 
Main Group - Nonstandard: 
 
 
  alloca  atand   atand2  bcopy   bzero    cosd    sind 
 
Printf functions: 
 
  fprintf printf sprintf 
 
 
Printf Nonstandard: 
 
 
  snprintf 
 
 
Standard math functions that set errno, 
 
thereby requiring /ASSUME=NOMATH_ERRNO: 
 
  acos    asinl   expf    log10    powl   sqrtf  tanh 
  acosf   cosh    expl    log10f   sinh   sqrtl  tanhf 
  acosl   coshf   log     log10l   sinhf  tan    tanhl 
  asin    coshl   logf    pow      sinhl  tanf 
  asinf   exp     logl    powf     sqrt   tanl 
 
 
Nonstandard math functions that set errno, 
 
thereby requiring /ASSUME=NOMATH_ERRNO: 
 
  log2 
  tand 

Also see Section 1.3.4 for a description of the [NO]INTRINSICS option of the /OPTIMIZE qualifier, which controls whether or not certain functions are handled as intrinsic functions without explicitly enabling each of them as an intrinsic through the #pragma intrinsic directive.

Also, the asm , fasm , and dasm functions are intrinsics and require use of #pragma intrinsic . See Section 6.2.1.2 for a description of these functions.

5.4.11 #pragma linkage Directive (ALPHA ONLY)

This section describes the behavior of the #pragma linkage directive on OpenVMS Alpha systems.

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.23, to associate a previously defined special linkage with a function.

For OpenVMS Alpha systems, the #pragma linkage directive has the following formats:


#pragma linkage linkage-name = (characteristics)
#pragma linkage_alpha linkage-name = (characteristics)

Both formats behave identically on OpenVMS Alpha systems. On I64 systems, however, register mapping occurs for the pragma linkage format, as described in Section 5.4.12.

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)
standard_linkage

If the standard_linkage keyword is specified, it must be the only option in the parenthesized list following the linkage name. For example:


#pragma linkage special1 = (standard_linkage) 

The standard_linkage keyword tells the compiler to use the standard linkage appropriate to the target platform. This can be useful to confine conditional compilation to the pragmas that define linkages, without requiring the corresponding #pragma use_linkage directives to be conditionally compiled as well.

Code written to use linkage pragmas as intended, treating them as target-specific without implicit mapping, might have a form like this:


#if defined(__alpha) 
#pragma linkage_alpha special1 = (__preserved(__r1,__r2)) 
#elif defined(__ia64) 
#pragma linkage_ia64 special1 = (__preserved(__r9,__r28)) 
#else 
#pragma message ("unknown target, assuming standard linkage") 
#pragma linkage special1 = (standard_linkage) 
#endif 

If the standard_linkage keyword is not specified, 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.

For OpenVMS Alpha systems, valid registers for the preserved , nopreserve , and notused options are:

  • General-purpose registers R0 through R30
  • Floating-point registers F0 through F30

Valid registers for the result and parameters options are:

  • General-purpose registers R0 through R25
  • 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 R5 and a sublist containing the registers F5 and F6:


nopreserve(f3, f4) 
parameters(r5, (f5, f6)) 

The following example shows a linkage using such characteristics:


#pragma linkage my_link=(nopreserve(f3,f4), parameters(r5,(f5,f6)), 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 R5, R6, and R7; the second is passed in F6:


struct sample_struct_t { 
    int A, B; 
    short C; 
    } sample_struct; 
 
 
#pragma linkage sample_linkage = (parameters ((r5, r6, r7), f6)) 
 
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.

HP 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:

  • ai ---Specifies that the Argument Information register (R25) does not need to be set up when calling the specified functions.
  • lp ---Specifies that the Linkage Pointer register (R27 for Alpha systems) does not need to be set up when calling the specified functions. The linkage pointer is required when the called function accesses global or static data. For I64 systems, there is no linkage pointer, so this setting is accepted but does not change the behavior of the pragma.

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. Also, functions that use the __RETURN_ADDRESS built-in function or va_count C RTL function cannot be called with a special linkage.


Previous Next Contents Index