Pragma Directives

You typically use a #pragma directive to control the actions of the compiler in a particular portion of a translation unit without affecting the translation unit as a whole.

Put pragmas in your C++ source code where you want them to take effect. Unless otherwise noted below, a pragma is in effect from the point where it is included until the end of the translation unit or until another pragma changes its status.

Note that,

Syntax:

#pragma pragma-string
pragma-string can be one of the following instructions to the compiler with any required parameters.

See Also: Pragmas for Improving Shared Library Performance


Pragma ALIGN

Syntax:

#pragma align N

Where N is a number raised to the power of 2.

Description:

Both PA and Itanium®-based aCC support 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, then a warning message is displayed, and the pragma is ignored.

Example:

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


Pragma COPYRIGHT

Syntax:

#pragma COPYRIGHT "string"
string is the set of characters included in the copyright message in the object file.

Description:

Specifies a string to include in the copyright message and puts the copyright message into the object file.

If no date is specified (using pragma COPYRIGHT_DATE), the current year is used in the copyright message.

Examples:

Assuming the year is 1999, the directive

#pragma COPYRIGHT "Acme Software"

places the following string in the object code:

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

The following pragmas

#pragma COPYRIGHT_DATE "1990-1999"
#pragma COPYRIGHT "Brand X Software"
place the following string in the object code:
(C) Copyright Brand X Software, 1990-1999. All rights reserved.
No part of this program may be photocopied, reproduced, or
transmitted without prior written consent of Brand X Software.

NOTE: To see the COPYRIGHT string as well as any other strings in the object file, use the strings(1) command with the -a option. For example:

strings -a ObjectFileName.o


Pragma COPYRIGHT_DATE

Syntax:

#pragma COPYRIGHT_DATE "string"
string is a date string used by the COPYRIGHT pragma.

Description:

Specifies a date string to be included in the copyright message.

Use the COPYRIGHT pragma to put the copyright message into the object file.

Example:

#pragma COPYRIGHT_DATE "1988-1992"
Places the string "1988-1992" in the copyright message.

NOTE: To see the COPYRIGHT_DATE string as well as any other strings in the object file, use the strings(1) command with the -a option. For example:

strings -a ObjectFileName.o


Pragma EXTERN

Syntax:

#pragma EXTERN [symbol{,symbol}]

Description:

The specified symbols, or all undefined symbols if no list is provided, are assigned to the default export class. Additionally, the compiler will inline the import stub for calls to these symbols. No compile time binding of these symbols will be done. All references to these symbols will be through the linkage table, so an unnecessary performance penalty will occur if extern is applied to a listed symbol that is resolved in the same load module. This is the pragma equivalent of -Bextern and is global in scope.


Pragma FINI

Syntax:

#pragma FINI string

Description:

Use the #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.

Example:

#pragma FINI "my_fini"
void my_fini() { ... do some clean up ... }


Pragma HP_ALIGN

Syntax:

#pragma HP_ALIGN align_mode [PUSH]
#pragma HP_ALIGN POP

Note:This option is supported in legacy HP C only. In aC++, you can use Pragma PACK.

Description:

This pragma controls the alignment of data storage allocation and alignment of structures, unions, and type definitions using typedefs.

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. 

The defined values for align_mode are:

  #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. 

  #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. 

  #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. 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. 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.


Pragma HP_DEFINED_EXTERNAL

Syntax:

#pragma HP_DEFINED_EXTERNAL name1[,name2,...nameN]

Description:

The specified symbols, or all undefined symbols if no list is provided, are assigned to the default export class. Additionally, the compiler will inline the import stub for calls to these symbols. No compile time binding of these symbols will be done. All references to these symbols will be through the linkage table, so an unnecessary performance penalty will occur if extern is applied to a listed symbol that is resolved in the same load module. This is the pragma equivalent of -Bextern and is global in scope

This pragma is equivalent to the #pragma EXTERN.


Pragma HP_DEFINED_INTERNAL

Syntax:

#pragma HP_DEFINED_INTERNAL name1[,name2,...nameN]

Description:

The specified symbols, or all symbols if no symbols are specified, are assigned the protected export class. That means these symbols will not be preempted by symbols from other load modules, so the compiler may bypass the linkage table for both code and data references and bind them to locally defined code and data symbols. This pragma is equivalent to -Bprotected and is global in scope.


Pragma HP_SHLIB_VERSION

Syntax:

#pragma HP_SHLIB_VERSION ["]date["]
The date argument is of the form month/year, optionally enclosed in quotes.

Description:

Creates different versions of a routine in a shared library.

HP_SHLIB_VERSION assigns a version number based on date to a module in a shared library. The version number applies to all global symbols defined in the module's source file.

This pragma should only be used if incompatible changes are made to a source file. If a version number pragma is not present in a source file, the version number of all symbols defined in the object module defaults to 1/90.

For More Information:


Pragma INIT

Syntax:

#pragma INIT string

Description:

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

Example:

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


Pragma LOCALITY

Syntax:

#pragma LOCALITY "string"
string specifies a name to be used for a code section.

Description:

Specifies a name to be associated with the code written to a relocatable object module. The string is forced to be upper case in C.

All code following the LOCALITY pragma is associated with the name specified in string. Code that is not headed by a LOCALITY pragma is associated with the name .text.

The smallest scope of a unique LOCALITY pragma is a function.

Example:

#pragma LOCALITY "MINE"
Builds the name .text.MINE and associates all code following this pragma with this name, unless another LOCALITY pragma is encountered.

Note:This pragma is supported in legacy HP C and C++ C-mode only.


Pragma LOCALITY_ALL

Syntax:

#pragma LOCALITY_ALL string

Description:

The LOCALITY_ALL pragma specifies a name to be associated with the linker procedures and global variables that should be grouped together at program binding or load time. These are written to a relocatable object module. All procedures and global variables following the LOCALITY_ALL pragma are associated with the name specified in the string.


Pragma [NO]INLINE

Syntax:

#pragma [NO]INLINE sym[, sym]

Description:

The [NO]INLINE pragma enables[disables] inlining for all functions or specified functionname(s).

Example:

To specify inlining of the two subprograms checkstat and getinput, use:
#pragma INLINE checkstat, getinput
To specify that an infrequently called routine should not be inlined when compiling at optimization level 3 or 4, use:
#pragma NOINLINE opendb

See Also:

+O[no]inline Option

Note:This pragma is supported in legacy HP C and C++ C-mode only.


Pragma NO_INLINE

Syntax:

#pragma NO_INLINE

Description:

This is a synonym for #pragma NOINLINE. The NO_INLINE pragma disables inlining for all functions or specified functionname(s).

See Also:

Note:This pragma is supported in legacy HP C and C++ C-mode only.


Pragma NO_SIDE_EFFECTS

Syntax:

  #pragma NO_SIDE_EFFECTS functionname,..., functionnameN

Description:

This pragma 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.

Example:

  #pragma NO_SIDE_EFFECTS foo

  // where foo is name of a function.


Pragma OMP ATOMIC

Syntax:

#pragma omp atomic 
          expression-stmt
where expression stmt must have one of the following forms: where,

x is an lvalue expression with scalar type.
expr is an expression with scalar type, and it does not reference the object designated by x.

Description:

The atomic directive ensures that a specific memory location is updated atomically, rather than exposing it to the possibility of multiple, simultaneous writing threads.


Pragma OMP BARRIER

Syntax:

#pragma omp barrier 

Description:

The barrier pragma synchronizes all the threads in a team. When encountered, each thread waits until all the threads in the team have reached that point.

The smallest statement to contain a barrier must be a block or a compound statement. barrier is valid only inside a parallel region and outside the scope of for, section/sections, critical, ordered, and master.


Pragma OMP CRITICAL

Syntax:

#pragma omp critical [(name)] 
           structured-block 

The name parameter is optional. All unnamed critical sections map to the same name.

Description:

The critical pragma identifies a construct that restricts the execution of the associated structured block to one thread at a time.


Pragma OMP FOR

Syntax:

#pragma omp for [clause1,clause2, ...]
          
           for-loop
where [clause1, clause2, ...] indicates that the clauses are optional. There can be zero or more clauses.

clause may be one of the following:

Description:

The for pragma identifies a work-sharing construct that specifies a region in which the iterations of the associated loop will be executed in parallel. The iterations of the loop are distributed across threads that already exist.


Pragma OMP FLUSH

Syntax:

#pragma omp flush [(list)] 

where (list) names the variables that will be synchronized.

Description:

The flush directive, whether explicit or implied, specifies a cross-thread sequence point at which the implementation is required to ensure that all the threads in a team have a consistent view of certain objects in the memory.

A flush directive without a list is implied for the following directives:

Note:The directive is not implied if a nowait clause is present.


Pragma OMP MASTER

Syntax:

#pragma omp master 

          structured-block 

Description:

The master pragma directs that the structured block following it should be executed by the master thread (thread 0) of the team. Other threads in the team do not execute the associated block.


Pragma OMP ORDERED

Syntax:

#pragma omp ordered  
          structured-block

Description:

The ordered pragma indicates that the following structured block should be executed in the same order in which iterations will be executed in a sequential loop.

An ordered directive must be within the dynamic extent of a for or a parallel for construct that has an ordered clause. When the ordered clause is used with schedule which has a chunksize, then the chunksize is ignored by the compiler.


Pragma OMP PARALLEL

Syntax:

#pragma omp parallel [clause1, clause2,...] 
            structured-block 
where [clause1, clause2, ...] indicates that the clauses are optional. There can be zero or more clauses.

clause can be one or more of the following:

Description:

The parallel pragma defines a parallel region, which is a region of the program that is executed by multiple threads in parallel. This is the fundamental construct that starts parallel execution.


Pragma OMP PARALLEL FOR

Syntax:

#pragma omp parallel for [clause1, clause2, ... ]

          for-loop

where [clause1, clause2, ...] indicates that the clauses are optional. There can be zero or more clauses.

Description:

The parallel for pragma is a shortcut for a parallel region that contains a single for pragma. parallel for admits all the allowable clauses of the parallel pragma and the for pragma except for the nowait caluse.


Pragma OMP PARALLEL SECTIONS

Syntax:

#pragma omp parallel sections [clause1, clause2, ...]

{
   [#pragma omp section  ]
            structured-block
   [#pragma omp section  
            structured-block ]
. . .
}

where [clause1, clause2, ...] indicates that the clauses are optional. There can be zero or more clauses.

Description:

The parallel sections pragma is a shortcut for specifying a parallel clause containing a single sections pragma. parallel sections admits all the allowable clauses of the parallel pragma and the sections pragma except for the nowait clause.


Pragma OMP SECTIONS

Syntax:

#pragma omp sections [clause1, clause2, ...]
{
#pragma omp section 
         [ structured-block ]
[#pragma omp section 
           structured-block ]
. . .
}

where [clause1, clause2, ...] indicates that the clauses are optional. There can be zero or more clauses.

clause may be one of the following:

Description:

The section/sections pragmas identify a construct that specifies a set of constructs to be divided among threads in a team. Each section is executed by one of the threads in the team.


Pragma OMP SINGLE

Syntax:

#pragma omp single [clause1, clause2, . . .] 

          [ structured-block ]

where [clause1, clause2, ...] indicates that the clauses are optional. There can be zero or more clauses.

clause may be one of the following:

Description:

The single directive identifies a construct that specifies the associated structured block that is executed by only one thread in the team (not necessarily the master thread).


Pragma OMP THREADPRIVATE

Syntax:

#pragma omp threadprivate (list) 

where the (list) is a comma-separated list of variables that do not have an incomplete type.

Description:

The threadprivate directive makes the named file-scope, namescope-scope, or static block-scope variables private to a thread.


OpenMP Clauses

Clauses on directives may be repeated as needed, subject to the restrictions listed in the description of each clause. The order in which clauses appear in directives is not significant. If variable-list appears in a clause, it must specify only variables. The following is the list of clauses in OpenMP directives:

private

Syntax:

private(list)

Description:

The private clause declares the variables in the list to be private to each thread in a team. A new object with automatic storage duration is allocated within the associated structured block for each thread in the team.

firstprivate

Syntax:

firstprivate(list)

Description:

The firstprivate clause provides a superset of the functionality provided by the private clause. Variables specified in the list have private clause semantics described earlier. The new private object is initialized, as if there is an implied declaration inside the structured block and the initializer is the value of the original object.

lastprivate

Syntax:

lastprivate(list)

Description:

When lastprivate clause is specified in a loop or section, the value of the lastprivate variable from either the sequentially last iteration of the associated loop, or the lexically last section directive is assigned to the variable's original object. The lastprivate clause provides a superset of the functionality provided by the private clause. Variables specified in the list have private clause semantics described earlier.

copyprivate

Syntax:

copyprivate(list)

Description:

The copyprivate clause can be used to broadcast values acquired by a single thread directly to all instances of the private variables in the other threads.
Note:The copyprivate clause can only appear on the single directive.

if

Syntax:

if(scalar-expression)

Description:

The associated block of code will be executed in parallel if the scalar-expression) evaluates to a non-zero value. Otherwise no parallelization happens and it is executed sequentially.

Example:

#pragma omp parallel private(x) if (a>b) reduction(+:p)
{
   // code to be parallelized only when a is greater than b
}

default

Syntax:

default(shared|none)

Description:

Specifying default(shared) clause is equivalent to explicitly listing each currently visible variable in a shared clause unless it is threadprivate or const-qualified. A variable referenced in the scope of default(none) should be explicitly qualified by a private or shared clause.

shared

Syntax:

shared(list)

Description:

The shared clause causes the variables that appear in the list to be shared among all threads in a team. All threads within a team access the same storage area for the shared variables

copyin

Syntax:

copyin(list)

Description:

The copyin clause copies the value of master thread's copy of a threadprivate variable to all other threads at the beginning of the parallel region. This clause can only be used with the parallel directive.

reduction(op:list

Syntax:

reduction(op:list)

Description:

The reduction clause performs a reduction on the scalar variables that appear in the list, with the operator op.

nowait

Syntax:

nowait

Description:

The nowait clause removes the implicit barrier synchronization at the end of a for or sections construct.

ordered

Syntax:

ordered

Description:

The ordered clause must be present when ordered directives bind to the for construct.

schedule

Syntax:

schedule(kind[,chunksize])

Description:

The schedule clause specifies how iterations of the for loop are divided among threads of the team. The kind of schedule can be: static, dynamic, guided, or runtime. chunksize should be a loop invariant integer expression.

num_threads

Syntax:

num_threads(interger-expression)

Description:

The num_threads clause allows a user to request a specific number of threads for a parallel construct. If the num_threads clause is present, then the value of the integer expression is the number of threads requested.


Pragma OPTIMIZE

Syntax:

#pragma OPTIMIZE ON
#pragma OPTIMIZE OFF

Description:

This pragma is used to toggle optimization on/off for different sections of source code as these pragmas are encountered in a top to bottom read of a source file.

NOTE:

Example:

aCC +O2 prog.C

#pragma OPTIMIZE OFF
void A(){    // Turn off optimization
    ...      // for this function
}

#pragma OPTIMIZE ON
void B(){    // Restore optimization
    ...      // to level 2.
}


Pragma OPT_LEVEL

Syntax:

#pragma OPT_LEVEL 0
#pragma OPT_LEVEL 1
#pragma OPT_LEVEL 2
#pragma OPT_LEVEL 3
#pragma OPT_LEVEL 4

Description:

The OPT_LEVEL pragma sets the optimization level to 0, 1, 2, 3, or 4.

NOTE:

Example:

aCC -O prog.C

#pragma OPT_LEVEL 1
void A(){      // Optimize this function at level 1.
   ...
}
#pragma OPT_LEVEL 2
void B(){      // Restore optimization to level 2.
   ...
}

Pragma PACK

Syntax:

#pragma PACK [n]
Where n can equal 1, 2, 4, 8, or 16 bytes. If n is not specified, maximum alignment is set to the default value.

Description:

This file-scoped pragma allows you to specify the maximum alignment of class fields having non-class types. The alignment of the whole class is then computed as usual, to the alignment of the most aligned field in the class.

NOTE: The result of applying #pragma pack n to constructs other than class definitions (including struct definitions) is undefined and not supported. For example:

#pragma pack 1
int global_var; // Undefined behavior: not a class definition

void foo() {    // Also undefined
}

Usage

The pack pragma may be useful when porting code between different architectures where data type alignment and storage differences are of concern. Refer to the following examples:

Refer also to Default Data Storage and Alignment.

Basic Example

The following example illustrates the pack pragma and shows that it has no effect on class fields unless the class itself was defined under the pragma.
Example 1:

struct S1 {
   char c1;  // Offset 0, 3 bytes padding
   int i;    // Offset 4, no padding
   char c2;  // Offset 8, 3 bytes padding
};  // sizeof(S1)==12, alignment 4

#pragma pack 1

struct S2 {
   char c1;  // Offset 0, no padding
   int i;    // Offset 1, no padding
   char c2;  // Offset 5, no padding
};  // sizeof(S2)==6, alignment 1

// S3 and S4 show that the pragma does not affect class fields
// unless the class itself was defined under the pragma.
struct S3 {
   char c1;  // Offset 0, 3 bytes padding
   S1 s;     // Offset 4, no padding
   char c2;  // Offset 16, 3 bytes padding
};  // sizeof(S3)==20, alignment 4

struct S4 {
   char c1;  // Offset 0, no padding
   S2 s;     // Offset 1, no padding
   char c2;  // Offset 7, no padding
};  // sizeof(S4)==8, alignment 1

#pragma pack

struct S5 {  // Same as S1
   char c1;  // Offset 0, 3 bytes padding
   int i;    // Offset 4, no padding
   char c2;  // Offset 8, 3 bytes padding
};  // sizeof(S5)==12, alignment 4

Template Example

If the pragma is applied to a class template, every instantiation of that class is influenced by the pragma value in effect when the template was defined.

CAUTION: The alignment of specializations and partial specializations of templates is undefined and unsupported if either the primary template or the specialization is under the influence of a #pragma pack directive.

Example 2:

#pragma pack 1

template<class T>
struct ST1 {
char c1;
T x;
char c2;
};

#pragma pack

ST1<int> obj;      // Same layout as S2 in the prior example

template <>        // Explicit specialization
struct ST1<void> {
   char c1;
   char c2;
};                       // Undefined (unsupported) behavior
                         // ST1 was defined under a #pragma pack 1
                         // directive.

Handling Unaligned Data

Direct access to unaligned class fields is handled automatically by HP aC++. However, this results in slower access times than for aligned data.

Indirect access (through pointers and references) to unaligned class fields is also handled automatically.

CAUTION: If you take the address of a data field and assign it to a pointer, it is not handled automatically and is likely to result in premature termination of the program if not handled appropriately. For example:

Example 3:

#include <stdio.h>
#pragma pack 1
struct S1 {
   char c1;
   int i;
   char c2;
};
#pragma pack
int main() {
	S1 s;
	S1 *p = &s;
	printf("%d\n", s.i);   // OK
	printf("%d\n", p->i);  // OK
	int *ip = &p->i;       // Undefined behavior
			       // Likely Abort unless compiled with +u1
		               // The address of a reference (*ip) is
		               // assigned to an int pointer.
	printf("%d\n", *ip);
}

To enable indirect access to unaligned data that has been assigned to another type, use the following:

Implicit Access to Unaligned Data

Calls to non-static member functions require that an implicit this pointer be passed to these functions, which can then indirectly access data through this implicit parameter. If such an access is to unaligned data, the situation in the prior Example 3 occurs.

Furthermore, virtual function calls often require indirect access to a hidden field of a class that could be unaligned under the influence of the #pragma pack directive.

If passing the address of a field to other code, consider the following example. Unless compiled with -DRECOVER on the command line and linked with -lunalign, Example 4 is likely to prematurely terminate with a bus error.

Example 4:

#include <stdio.h>
#ifdef RECOVER
extern "C" void allow_unaligned_data_access();
#endif

#pragma pack 1

struct PS1 {
   PS1();
   ~PS1();
private:
   char c;
   int a;
};

#pragma pack

PS1::PS1(): a(1) {   // There appears to be no pointer, but there
                     // is an unaligned access, possibly through "this."
   printf("In constructor.\n");
}

PS1::~PS1() {
   a = 0;           // Misaligned access, possibly though "this"
   printf("In destructor.\n");
}

int main() {
#if defined(RECOVER)
   allow_unaligned_data_access();
#endif
   PS1 s;
}


Pragma UNALIGN

Syntax

#pragma unalign [1|2|4|8|16]
typedef T1 T2;

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

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.

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 by 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

Also see:

HP_ALIGN and unalign pragma:
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. For more information on HP_ALIGN pragma, see HP ANSI C Programmer's Guide.


Pragma UNROLL_FACTOR

Syntax

#pragma UNROLL_FACTOR n

Description:

This block-scoped pragma applies the unroll factor for a loop containing the current block. You can apply an unroll factor, which you think is best for the given loop or apply no unroll factor to the loop. If this pragma is not specified, compiler uses its own heuristics to determine the best unroll factor for the inner loop.

A user specified unroll factor will override the default unroll factor applied by the compiler.
Specifying n=1 will prevent the compiler from unrolling the loop so as to form n copies of the original body.
Specifying n=0 allows the compiler to use its own heuristics to apply the unroll factor.

Note:UNROLL_FACTOR pragma will be ignored if it is placed in a loop other than the innermost loop.


Pragma VERSIONID

Syntax:

#pragma VERSIONID "string"
string is a string of characters that HP aC++ places in the object file.

Description:

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.

Example:

#pragma VERSIONID "Software Product, Version 12345.A.01.05"

Places the characters Software Product, Version 12345.A.01.05 into the object file.

NOTE:To see the VERSIONID string as well as any other strings in the object file, use the strings(1) command with the -a option. For example:

strings -a ObjectFileName.o

Pragma VTABLE

Syntax:

# pragma vtable [ OFF_IF_NO_KEY_BEGIN | OFF_IF_NO_KEY_END ]

Description:

The vtable pragma provides source level control over how C++ vtables are emitted. In aCC a virtual table (vtable) is generated for a virtual class only when the key function's definition is found. The key function is the first non-inline member function. This saves having to generate the vtable in each compilation unit where the class is used.

However, in the case a class has no key function (not uncommon) the vtable is forced to be generated in a comdat section, and each compilation unit containing the class declaration will get a vtable for this class.

The pragma is enabled with OFF_IF_NO_KEY_BEGIN and disabled with OFF_IF_NO_KEY_END. The pragma does not nest and no warning is given if it is. This is because the pragma is disabled after the first OFF_IF_NO_KEY_END.

There are a number of such classes in the stdlib headers. These headers have been modified to take advantage of this new pragma.

Example:

  // Use "-DEMIT_SELECTED_VTABLE" once for a set of compilation units
  #ifndef EMIT_SELECTED_VTABLE
  #pragma vtable  OFF_IF_NO_KEY_BEGIN 
  #endif 
  class A {
       virtual int f_A(); // key function -- vtable will be generated
                          // where f_a() is defined. pragma has no effect.
  };
  class B {
       virtual int f_B() { return 0; } // not a key function: inline. 
                                       // The pragma inhibits generation of a 
                                       // vtable.
  };
  #ifndef EMIT_SELECTED_VTABLE
  #pragma vtable  OFF_IF_NO_KEY_END
  #endif 
Currently this pragma needs to explicitly turned by setting the environment variable aCC_ENABLE_VTBL_OMISSION to ON.


Pragmas for Improving Shared Library Performance


The pragmas described here can improve the performance of shared libraries by reducing the overhead of calling shared library routines. All three pragmas should be used together, where applicable, as they depend on one another to a certain extent. You must be very careful in using them because incorrect use can result in incorrect and unpredictable behavior. See the HP-UX Online Linker and Libraries User's Guide for more information on improving shared library performance.


Pragma HP_NO_RELOCATION

Syntax:

#pragma HP_NO_RELOCATION name1[,name2,...nameN]

name1 through nameN are names of functions in shared libraries. Note that C++ mangled names are not supported.

Any named function:

Description:

This pragma improves performance of shared library calls by omitting floating-point parameter relocation stubs in calls to shared library functions.

Parameter relocation stubs are instructions that move (relocate) floating-point parameters and function return values between floating-point registers and general registers. They are generated for calls to routines in shared libraries. Relocation stubs are generated when passing floating-point parameters or using a floating-point function return in routines in shared libraries. The HP_NO_RELOCATION pragma prevents this unnecessary relocation.

Usage

Put the HP_NO_RELOCATION pragma in header files of functions that take floating-point parameters or return floating-point data and that will be placed in shared libraries. Putting it in the header file and ensuring all calls reference the header file is one way to ensure that it is specified at the function definition and at all calls.

This pragma is automatically supplied by HP aC++ for non-static member functions.


WARNING: The HP_NO_RELOCATION pragma must be at the function definition and at all call sites. If the pragma is omitted from the function definition or from any call, the linker will generate parameter relocation code and the application will behave incorrectly since floating-point parameters will not be in expected registers.


CAUTION: Do not use the HP_NO_RELOCATION pragma with functions that use the stdarg macros. See the stdargs(5) man page for information on stdargs macros.


Pragma HP_LONG_RETURN

Syntax:

#pragma HP_LONG_RETURN name1[,name2,...nameN]

name1 through nameN are names of functions in shared libraries. Note that C++ mangled names are not supported.

Any named function:

Description:

This pragma improves performance of shared library calls by using a long return instruction sequence instead of an interspace branch and by omitting export stubs.

An export stub is a short code segment generated by the linker for a global definition in a shared library. External calls to shared library functions go through the export stub. An export stub is generated by default for each function in a shared library. Each call to the function goes through the export stub. The export stub serves two purposes: to relocate parameters and perform an interspace return.

The HP_LONG_RETURN pragma generates a long return sequence in the export stub instead of an interspace branch. If you also use the HP_NO_RELOCATION pragma (for functions taking floating-point parameters), all the code in the export stub is omitted, eliminating the export stub entirely. For functions taking non-floating-point parameters, the HP_LONG_RETURN pragma by itself eliminates the need for export stubs.

Usage

Put this pragma in header files of functions that will go in shared libraries. Specify it at the function definition and at all calls. For functions with floating-point parameters or returns, use the HP_NO_RELOCATION pragma along with the HP_LONG_RETURN pragma.

This pragma is automatically supplied by HP aC++ for non-static member functions.

This pragma is not required if you compile on PA-RISC 2.0 or later or with the +DA2.0 option since the effect is the default. That is, if no relocations are generated, export stubs are not generated on PA-RISC 2.0 and later, and a long return instruction sequence is generated by default, so this pragma has no effect.


WARNING: The HP_LONG_RETURN pragma must be at the function definition and at all call sites. If the pragma is omitted from the function definition or from any call, the compiler will generate incompatible return code and the application will behave incorrectly and likely abort.


CAUTION:

With floating-point parameters, using HP_LONG_RETURN without using HP_NO_RELOCATION could actually degrade performance by creating export stubs and relocation stubs.

These pragmas improve performance of calls to shared library functions from outside the shared library. Therefore do not use this pragma for hidden functions (see the -h and +e linker options) nor for functions called only from within the same shared library linked with the -B symbolic linker option, otherwise this pragma may degrade performance. (See the HP-UX Online Linker and Libraries User's Guide for information on the above mentioned options.)


Pragma hdr_stop

Syntax:

#pragma hdr_stop

Description:

When you request header caching with the +hdr_cache option, this pragma specifies the end of the prefix header region.

In a given source file, this pragma cannot be reset. It only allows the prefix header region to be shortened, not expanded. Also, there is no equivalent hdr_start pragma to alter the beginning of the prefix header region.

If the #pragma hdr_stop occurs as the first line in a source file, header caching is abandoned for that source file. If it occurs as the first line in a header file, header caching is abandoned for the source file that includes the header file.

Usage

If you do not want certain headers precompiled, no matter what source file they are included in, instead of searching for all the sources that include them and turning the +hdr_cache option off for each of those sources, you can specify #pragma hdr_stop as the first line in each such header file.

Another example might be useful when only a subset of headers are undergoing code changes. You could place these headers at the end of the list of #include directives, after specifying #pragma hdr_stop. Then, if the more stable headers comprising the prefix header region and the compile environment itself do not change, no re-compile will take place.

Examples

In the following example, using the default prefix header region, changes to any header file will cause a re-compile.
#include <vector>     // stable headers
#include <list>
#include <SuperBase>
#include <IOBase>

#include <Magikal>    // headers you are changing
#include <Util>
                            // default END of prefix header region
void poof();
In the next example, by ending the prefix header region prior to the headers you are changing, a re-compile does not occur unless changes are made to a stable header file.
#include <vector>     // stable headers
#include <list>
#include <SuperBase>
#include <IOBase>

#pragma hdr_stop            // END the prefix header region
                            // prior to the default

#include <Magikal>    // headers you are changing
#include <Util>

void poof();

For More Information: