HPlogo HP-UX/HP C Compiler: HP C/HP-UX Reference Manual > Chapter 9 Compiling and Running HP C Programs

Pragmas

» 

Technical documentation

Complete book in PDF

 » Table of Contents

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

  • intrinsic pragmas

  • copyright notice and identification pragmas

  • data alignment pragmas

  • optimization pragmas

  • program listing pragmas

  • shared library pragmas

  • fast libcall pragmas

Refer to the HP C/HP-UX Programmer's Guide for information on parallel processing pragmas and for additional information.

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 FINI "string"

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.

Intrinsic Pragmas

See Chapter 11 “Using Intrinsics ” for further information about the pragmas introduced here.

INTRINSIC Pragma

#pragma INTRINSIC intrinsic_name1
[user_name] [,intrinsic_name2]
[user_name]...

Declares an external name as an intrinsic.

INTRINSIC_FILE Pragma

#pragma INTRINSIC_FILE "path"

Specifies the path of a file in which the compiler can locate information about intrinsic functions. See Chapter 11 “Using Intrinsics ” for further information about the intrinsics pragmas.

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, #pragma locality "mine" will build the name "$CODE$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.

HP_ALIGN Pragma

#pragma HP_ALIGN align_mode [PUSH]

#pragma HP_ALIGN POP
Data Alignment Stack

The PUSH and POP options allow functions to establish their own alignment environment for the duration of the function call, and restore the alignment environment previously in effect when exiting the procedure.

The HP_ALIGN pragma must have a global scope (outside of any function, enclosing structure, or union).

#pragma HP_ALIGN POP

This option to HP_ALIGN restores the previous alignment environment saved using the HP_ALIGN PUSH pragma by deleting the current alignment mode from the top of the stack. If the alignment stack is empty, the default alignment is made the current mode.

#pragma HP_ALIGN align_mode PUSH

This pragma saves the current alignment environment for later retrieval by pushing it into a last in, first out (LIFO) stack. The align_mode is made the new current alignment by placing it on the top of the stack.

Alignment Modes

align_mode can be any of the following values:

#pragma HP_ALIGN HPUX_WORD

Results in int and float types being halfword aligned (two-byte aligned), doubles being word aligned (four byte aligned), and all structs being at least halfword aligned. This is the default for the Series 300/400 computer.

#pragma HP_ALIGN HPUX_NATURAL_S500

Results in doubles being word aligned. This is the default for the Series 500 computer.

#pragma HP_ALIGN HPUX_NATURAL

Results in native alignment for the HP 9000 workstations and servers. The int and float types are word aligned, doubles are double-word aligned (8-byte aligned), and structs may be byte aligned depending upon the data types used within the structure.

#pragma HP_ALIGN NATURAL

Results in a superset of the above. Uses native alignment provided by HPUX_NATURAL, all structs and unions are at least halfword aligned, and DOMAIN bit-field mapping is used. (See Chapter 2, "Storage and Alignment Comparisons," in the HP C/HP-UX Programmer's Guide for details regarding Domain bit-fields.)

#pragma HP_ALIGN DOMAIN_NATURAL

Similar to NATURAL except long doubles are only 8 bytes long (treated as doubles).

#pragma HP_ALIGN DOMAIN_WORD

Similar to HPUX_WORD, with the following exceptions: long doubles are only 8 bytes long (treated as doubles) and DOMAIN bit-field mapping is used. (See Chapter 2, "Storage and Alignment Comparisons," in the HP C/HP-UX Programmer's Guide for details regarding Domain bit-fields.)

#pragma HP_ALIGN NOPADDING

Causes all structure and union members that are not bit-fields to be packed on a byte boundary. It does not cause crunched data packing, where there are zero bits of padding. It only ensures that there will be no full bytes of padding in the structure or union.

Accessing Data with the HP_ALIGN Pragma

The HP_ALIGN pragma isolates data structures that are not naturally aligned for PA-RISC systems.

References to non-natively aligned data often results in poorer run-time performance than references to natively aligned data. Natively aligned data is often accessed with a single load or store instruction. Non-natively aligned data must be accessed with one or more load and store instructions.

The HP_ALIGN pragma differs from the +ubytes compiler option. When you use the HP_ALIGN pragma, the compiler localizes inefficient code generation to accesses of data declared with structures or unions under the HP_ALIGN pragma. The +ubytes option assumes that all references to pointer objects are misaligned and performs worst case code generation for all loads and stores of dereferenced data.

The HP_ALIGN pragma offers better run-time performance than the +unumber option. However, the HP_ALIGN pragma requires careful pointer assignment and dereferencing. The following example shows how the pragma is often misused, and what can be done to correct the mistake.

#pragma HP_ALIGN HPUX_WORD

struct {
char chardata;
int intdata;
} stvar;



main()
{
int *localptr;
int localint;
localptr = &stvar.intdata;
localint = *localptr; /* invalid dereference */
}

The above program aborts at run-time when localptr is dereferenced. The structure stvar is declared under the HP_ALIGN HPUX_WORD pragma. Its members will not be natively aligned for PA-RISC. The member stvar.intdata is aligned on a two byte boundary.

The error occurs after the address of stvar.intdata is assigned to localptr. localptr is not affected by the HP_ALIGN HPUX_WORD pragma. When localptr is used to access the data, it is treated as a pointer to four-byte aligned data rather than as a pointer to two-byte aligned data and a run-time error can occur.

Two solutions help to work around this problem. First, the recommended solution is to access non-natively aligned data through structures or unions that are declared under the HP_ALIGN pragma.

For example, the above program can be transformed to:

#pragma HP_ALIGN HPUX_WORD

struct {
char chardata;
int intdata;
} stvar; /* stvar is declared under the HP_ALIGN pragma */



main()
{
int *localptr;
int localint;
localint = stvar.intdata; /* Valid access of non-naturally */
/* aligned data through a struct */
}

The second method is to inform the compiler that all access of data must assume potentially non-natural alignment. In the case of #pragma HP_ALIGN HPUX_WORD shown in the first example above, you can use the +u2 command line option. This causes all loads and stores of any data to be performed in increments of no greater than 2-bytes at a time.

For complete details about the +ubytes option, see Table 9-2 “HP C Compiler Option Details ”.

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.

Listing Pragmas

The listing pragmas introduced in this section are discussed in more detail in Chapter 12 “The Listing Facility ”.

LINES Pragma

#pragma LINES linenum

Sets the number of lines per page to linenum. The default is 63. The minimum number of lines per page is 20.

WIDTH Pragma

#pragma WIDTH pagewidth

Sets the width of the page to pagewidth. The default is 80 columns. The minimum number of columns per page is 50. Place the WIDTH pragma before any TITLE or SUBTITLE pragmas. The width of the title and subtitle fields varies with the page width.

TITLE Pragma

#pragma TITLE "string"

Makes string the title of the listing. String can have a length of up to 44 characters less than the page width (additional characters are truncated with no warning). The default is no title.

SUBTITLE Pragma

#pragma SUBTITLE "string"

Makes string the subtitle of the listing. String can have a length of up to 44 characters less than the page width (additional characters are truncated with no warning). 8The default is no subtitle.

PAGE Pragma

#pragma PAGE

Causes a page break and begins a new page.

LIST Pragma

#pragma LIST { ON }
#pragma LIST { OFF }

Turns listing functionality ON or OFF when used with the -Wc,-L command line option. The default is ON. Use this pragma to exclude source lines you do not need to list such as include files.

AUTOPAGE Pragma

#pragma AUTOPAGE { ON }
#pragma AUTOPAGE { OFF }

ON causes a page break after each function definition. If the pragma is declared without specifying either the ON or OFF option, then page breaks are generated. If the pragma is not used then no page breaks are generated.

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.

ALLOCS_NEW_MEMORY Pragma

#pragma ALLOCS_NEW_MEMORY functionname1,...,functionnamen

States that the function functionname returns a pointer to new memory that it allocates or a routine that it calls allocates. This pragma provides additional information to the optimizer which results in more efficient code. (See the HP C/HP-UX Programmer's Guide for additional information.)

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]PTRS_STRONGLY_TYPED Pragma

#pragma PTRS_STRONGLY_TYPED BEGIN

#pragma PTRS_STRONGLY_TYPED END

#pragma NOPTRS_STRONGLY_TYPED BEGIN

#pragma NOPTRS_STRONGLY_TYPED END

Specifies when a subset of types are type-safe, providing a finer level of control that +O[no]ptrs_strongly_typed. The pragma will take precedence over the command line option, although sometimes both are required. 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.

Shared Library Pragma

This section describes a pragma for shared libraries. For detailed information on shared libraries, see the HP-UX Linker and Libraries Online User Guide.

HP_SHLIB_VERSION Pragma

#pragma HP_SHLIB_VERSION "mm/[yy]yy"

Assigns a version number to a shared library module. This enables you to store multiple versions of a subroutine in a shared library.

The version number is specified by mm/[yy]yy. mm represents the month, and must be from 1 to 12. [yy]yy represents the year, either in 2 digits or 4 digits. If the 2 digit form is used, it must be from 90 to 99, and will be interpreted as 1990 to 1999. The 4 digit form must be from 1990 to 7450.

This pragma provides a way to guard against unexpected side effects when a shared library is updated. You can put multiple versions of a routine in the library and ensure that programs use the correct version. The date in the SHLIB_VERSION pragma provides the version number. Programs call the version in the shared library with a date less than or equal to the date the program was linked.

The version number should only be incremented when changes made to a subroutine make the new version of the subroutine incompatible with previous versions.

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" on page 138.

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.

© Hewlett-Packard Development Company, L.P.