HPlogo HP C/HP-UX Reference Manual: Version A.05.55.02 > Chapter 9 Compiling and Running HP C Programs

Pragmas

» 

Technical documentation

Complete book in PDF

 » Table of Contents

 » Index

A #pragma directive is an instruction to the compiler. Put pragmas in your C source code where you want them to take effect, but do not use them within a function. A pragma has effect from the point at which it is included to the end of the translation unit (or until another pragma changes its status).

This section introduces the following groups of HP C compiler directives:

Initialization and Termination Pragmas

This section describes the INIT and FINI pragmas. These allow the user to set up functions which are called when a load module (a shared library or executable) is loaded (initializer) or unloaded (terminator). For example, when a program begins execution, its initializers get called before any other user code gets called. This allows some set up work to take place. In addition, when the user’s program ends, the terminators can do some clean up. When a shared library is loaded or unloaded with the shl_load or dlopen API, its initializers and terminators are also executed at the appropriate time.

INIT Pragma

#pragma INIT “string

Use the compiler pragma INIT to specify an initialization function. The functions take no arguments and return nothing. The function specified by the INIT pragma is called before the program starts or when a shared library is loaded.

For example:

#pragma INIT “my_init”
void my_init() {
   ...do some initializations ...
}

FINI Pragma

#pragma FINIstring

Use the compiler pragma FINI to specify a termination function. The function specified by the FINI pragma is called after the C program terminates by either calling the libc exit() function, returning from the main or _start functions, or when the shared library which contains the FINI is unloaded from memory. Like the function called by the INIT pragma, the termination function takes no arguments and returns nothing.

For example:

# pragma FINI “my-fini”
void my_fini() {
   ...do some clean up ...
}

The Linker +I Option

HP-UX 10.x style initializers are the same type supported in all HP-UX 10.x releases. These are called both before the user’s code is started or a shared library is loaded as well as when the shared library is unloaded. The linker option +I is used to create this type of initializer.

The function returns nothing but takes two arguments. The first is a handle to the shared library being initialized. This handle can be used in calling shl_load API routines. The second is set to non-zero at startup and zero at program termination.

$ ld -b foo.o +I my_10x_init -o libfoo.sl
#include <dl.h>
void my_10x_init(shl_t handle, int loading)
   {
     /* handle is the shl_load API handle for the shared library being initialized. */
     /* loading is non-zero at startup and zero at termination. */

     if (loading) {
        ... do some initializations ...

}    else {
       ... do some clean up ...
    }
}

This type is only supported when creating a shared library (linker -b option). Also note that it may not be called when the user’s program terminates. They are always called, however, if the library is explicitly unloaded as a result of a shl_load or dlopen API call.

All three types (INIT, FINI, and +I) are supported in 64-bit links. Only HP-UX 10.x style initializers are supported in 32-bit links.

Copyright Notice and Identification Pragmas

The following pragmas can be used to insert strings in code.

COPYRIGHT Pragma

#pragma COPYRIGHT "string"

Places a copyright notice in the object file, using the “string” argument and the date specified using COPYRIGHT_DATE. If no date has been specified using #pragma COPYRIGHT_DATE, the current year is used. For example, assuming the year is 1990, the directive #pragma COPYRIGHT "Acme Software" places the following string in the object code:

(C) Copyright Acme Software, 1990. All rights reserved. No part
of this program may be photocopied, reproduced, or transmitted
without prior written consent of Acme Software.

COPYRIGHT_DATE Pragma

#pragma COPYRIGHT_DATE "string"

Specifies a date string to be used in a copyright notice appearing in an object module.

LOCALITY Pragma

#pragma LOCALITY "string"

Specifies a name to be associated with the code written to a relocatable object module. All code following the LOCALITY pragma is associated with the name specified in string. The smallest scope of a unique LOCALITY pragma is a function.

For example, the following command builds the name “$CODE&MINE$”:

#pragma locality “mine”

Code that is not headed by a LOCALITY pragma is associated with the name $CODE$. An empty "string" causes the code name to revert to the default name of $CODE$.

VERSIONID Pragma

#pragma VERSIONID "string"

Specifies a version string to be associated with a particular piece of code. The string is placed into the object file produced when the code is compiled.

Data Alignment Pragmas

This section discusses the data alignment pragmas HP_ALIGN and PACK and their various arguments available on the HP 9000 workstations and servers, to control alignment across platforms. In the following discussion, a word represents a 32-bit data structure. Refer to Chapter 2, “Storage and Alignment Comparisons,” in the HP C/HP-UX Programmer's Guide for detailed information on the HP_ALIGN and PACK pragmas.

ALIGN Pragma

#pragma align N

N is a number raised to the power of 2.

HP aC++ supports user specified alignment for global data. The pragma takes effect on next declaration. If the align pragma declaration is not in the global scope or if it is not a data declaration, the compiler displays a warning message. If the specified alignment is lesser than the original alignment of data, a warning message is displayed, and the pragma is ignored.

#pragma align 2 char c;              // "c" is at least aligned on 2 byte boundary
#pragma align 64
   int i, a[10];     // "i" and array "a" are at least aligned 64 byte boundary.
                       // the size of "a" is still 10*sizeof(int)

PACK Pragma

#pragma PACK n

The PACK pragma is a simple, intuitive way for users to specify alignment. In the syntax, n is the byte boundary on which members of structs and unions should be aligned, and can be 1, 2, 4, 8, or 16.

The PACK pragma is not intended to be an “extension” of the HP_ALIGN pragma. It is, instead, a simple and highly portable way of controlling the alignment of aggregates. It has some significant differences with the HP_ALIGN pragma, including uniform bitfield alignment, uniform struct and union alignment, and the lack of PUSH and POP functionality.

For complete details on the use of HP_ALIGN and PACK pragmas, refer to Chapter 2, “Storage and Alignment Comparisons,” in the HP C/HP-UX Programmer's Guide.

UNALIGN Pragma

#pragma unalign [1|2|4|8|16]

typedef T1 T2;

T1 and T2 have the same size and layout, but with specified alignment requirements.

HP aCC supports misaligned data access using the unalign pragma. The unalign pragma can be applied on typedef to define a type with special alignment. The unalign pragma takes effect only on next declaration.

If the unalign pragma declaration is not in the global scope or if it is not a typedef, compiler displays a warning message. If the specified alignment is greater than the original alignment of the declaration, then an error message is displayed, and the pragma is ignored. For example,

#pragma unalign 1 
typedef int ua_int;           // ua_int is of int type
                              // with 1 byte alignment

typedef ua_int *ua_intPtr;    // this typedef is not affected
                              // affected by the above unalign
                              // pragma. it defines a pointer
                              // type which points to 1 byte
                                // aligned int

The interaction between pack and unalign pragmas is as follows:

#pragma pack 1
struct S {
   char c;
   int i;
};

#pragma pack 0

S s;
ua_int *ua_ip = &s.i;         // ua_ip points to 1 byte aligned int
*ua_ip = 2;                    // mis-aligned access to 1 byte aligned int
NOTE: The HP_ALIGN pragma, which is supported by HP ANSI C compiler, is not supported by aCC. The pack and unalign pragmas can replace most of the HP_ALIGN functionality.

Optimization Pragmas

For additional information on the following optimization pragmas see Chapter 4, “Optimizing C Programs,” and Chapter 8, “Threads and Parallel Processing,” of the HP C/HP-UX Programmer's Guide.

FLOAT_TRAPS_ON Pragma

#pragma FLOAT_TRAPS_ON { functionname,...functionname }

#pragma FLOAT_TRAPS_ON {_ALL }

Informs the compiler that you may have enabled floating-point trap handling. When the compiler is so informed, it will not perform loop invariant code motion (LICM) on floating-point operations in the functions named in the pragma. This pragma is required for proper code generation when floating-point traps are enabled and the code is optimized.

The _ALL parameter specifies that loop invariant code motion should be disabled for all functions within the compilation unit.

[NO]INLINE Pragma

#pragma INLINE [functionname1,...,functionnamen]

#pragma NOINLINE [functionname1,...,functionnamen]

Enables (or disables) inlining of functions. If particular functions are specified with the pragma, they are enabled (or disabled) for inlining. If no functions are specified with the pragmas, all functions are enabled (or disabled) for inlining. Refer to the HP C/HP-UX Programmer's Guide for details and examples.

NO_SIDE_EFFECTS Pragma

#pragma NO_SIDE_EFFECTS functionname1,...,functionnamen

States that functionname and all the functions that functionname calls will not modify any of a program's local or global variables. This pragma provides additional information to the optimizer which results in more efficient code. See the HP C/HP-UX Programmer's Guide for further information.

FastCall Pragmas

The compiler directives described in this section are designed to speed-up shared library calls. For more information about how these pragmas help shared library performance, see “Improving Shared Library Performance” in HP C/HP-UX Programmer’s Guide.

HP_DEFINED_EXTERNAL Pragma

#pragma HP_DEFINED_EXTERNAL sym1, sym2, ...

The externally defined symbol pragma specifies that the designated symbols are imported from another load module (program file or shared library). Note that this pragma currently works in 32-bit mode only. For 64-bit mode, see the option +Oextern.

HP_LONG_RETURN Pragma

#pragma HP_LONG_RETURN func1, func2, ...

The long return sequence pragma specifies that the named procedures can return directly across a space, without needing to return through an export stub. The main goal of this pragma is to eliminate export stubs, and better enable inlining of import stubs and $$dyncall functionality for indirect calls.

HP_NO_RELOCATION Pragma

#pragma HP_NO_RELOCATION func1, func2, ...

The no parameter/return relocation pragma is used to suppress unnecessary floating point argument relocation. When used, the burden is on the caller and callee to have their argument and their return values agree in which register files they are passed.

Gather/Scatter Prefetch Pragma

This release supports pragmas for prefetching the cache lines specified in the pragma.

Syntax

#pragma prefetch <argument>

The behavior of this pragma is similar to the HP_OPT_DATA pragma which prefetches the data specified. But the prefetch pragma can access cache lines that are accessed via a vector of indices.

<argument> can have only one argument per pragma and it must me an array element. For example, a[i].

The compiler generates instructions to prefetch the cache lines starting from the address of an argument. The caveat is that the values prefetched must be valid values. Reading off the end of an array may result in undefined behavior during runtime.

Example:

The function below prefetches ia and b, but not a[ia[i]] when compiled with +O2 +Odataprefetch +DA2.0 (or +DA2.0W).

testprefc2(int n, double *a, int *ia, double *b)

{
for (int i=0; i<n, i++) {
b[i]=a[ia[i]];
}
}
Recording this routine as

#define USER_SPECIFIED 30

testprefc2(int n, double *a, int *ia, double *b)
{
int dist=(int)USER_SPECIFIED;
int nend=max(0,n_dist); /* so as not to read past the end of is */
for(i=0;i<nend;i++) /* original loop is for (i=0;i<n;i++) */
{
#pragma prefetch ia[i+4*dist]
#pragma prefetch a[ia[i+dist]]
b[i]=a[ia[i]];
}
/* finish up last part with no prefetching */

for (int i=nend;i<n;i++)
b[i]=a[ia[i]];
}

© Hewlett-Packard Development Company, L.P.