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.

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 DEFAULT_BINDING

Syntax:

#pragma DEFAULT_BINDING [symbol{,symbol}]

Description:

Global symbols are assigned the default export class. These symbols may be imported or exported outside of the current load module. The compiler will access tentative and undefined symbols through the linkage table. Any symbol that is not assigned to another export class through use of another pragma (or -B option or the deprecated +O[no]extern option) will have the default export class.


Pragma ESTIMATED_FREQUENCY

Syntax:

#pragma ESTIMATED_FREQUENCY f

Description:

This block-scoped pragma allows you to tell the compiler your estimate of how frequently the current block is executed as compared to the immediately surrounding block. You can indicate the average trip count in the body of a for loop or the fraction of time a then clause is executed. Frequency, f can be expressed as a floating point or integer constant. The compiler accepts preprocessor expressions that evaluate to a compile time constant.

For an if/then/else statement, the number f should be less than 1.0 and represents the fraction of time the then is executed because the if condition is true.

For a loop, the number is the predicted iteration count. Values less than one are permitted to indicate a loop that is rarely executed.

The pragma should precede all executable statements in the body of the loop statement or if statement.


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 FLOAT_TRAPS_ON

Syntax:

#pragma FLOAT_TRAPS_ON [function {,function}]

Description:

Informs the compiler that the function(s) may enable 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 function(s) named in the pragma. This pragma is required for proper code generation when floating-point traps are enabled.

For example:

#pragma FLOAT_TRAPS_ON xyz,abc

informs the compiler and optimizer that xyz and abc have floating-point traps turned on and therefore LICM optimization should not be performed. A dummy name _ALL represents all functions.

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


Pragma FREQUENTLY_CALLED

Syntax:

#pragma FREQUENTLY_CALLED [symbol{,symbol}]

Description:

This file-scoped pragma identifies functions that are frequently called within the application. The pragma must be placed prior to any definition of or reference to the named function. If not, the behavior is undefined. FREQUENTLY_CALLED is independent of +Oprofile=use in that it overrides any dynamically obtained profile information.


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 HIDDEN

Syntax:

#pragma hidden [symbol{,symbol}]

Description:

The specified symbols, or all symbols if no symbols are specified, are assigned the hidden export class. The hidden export class is similar to the protected export class. 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. In addition, hidden symbols will not be exported outside the current load module. The linker may eliminate them from a shared library, but in an executable, they remain accessible to the debugger unless -Oprocelim is also specified. This is the pragma equivalent of -Bhidden and is global in scope.


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.

This pragma is equivalent to #pragma PROTECTED.


Pragma IF_CONVERT

Syntax:

#pragma IF_CONVERT

Description:

This block-scoped pragma instructs the compiler to If-Convert the current scope. There is no command line option equivalent.

If-Conversion is a compiler process that eliminates conditional branches by the use of predicates. The compiler is instructed to If-Convert all non-loop control flow nested within the current block.

For a discussion of predicates with an animated example, please see Intel documentation at this URL. Select Branch Handling, then Using Predication to Eliminate Branches.

http://developer.intel.com/software/products/itc/architec/itanium/arch_mod/index.htm

Without this pragma, the compiler would employ its own heuristics to determine whether to perform If-Conversion. With this pragma, If-Conversion is always performed.

If-Convert can be specified in a loop containing conditional branches other than the loop-back branch. This makes it more likely the compiler will modulo schedule the loop, as loops containing conditional branches cannot be modulo scheduled. The pragma can also be used for non-looping constructs.


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_RETURN

Syntax:

#pragma NO_RETURN function1, [function2, . . .]

Description:

Optimizer hint that the named functions never return to the call site.


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 PROTECTED

Syntax:

#pragma PROTECTED [symbol{,symbol}]

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 RARELY_CALLED

Syntax:

#pragma RARELY_CALLED [symbol{,symbol}]

Description:

This file-scoped pragma identifies functions that are rarely called within the application. The pragma must be placed prior to any definition of or reference to the named function. If not, the behavior is undefined. RARELY_CALLED is independent of +Oprofile=use in that it overrides any dynamically obtained profile information.


Pragma STDC CX_LIMITED_RANGE

Syntax:

#pragma STDC CX_LIMITED_RANGE ON
#pragma STDC CX_LIMITED_RANGE OFF 

Description

This pragma enables limited range mathematical behavior for specific blocks of code. Note that, this pragma applies to complex arithmetic only. Also see ISO/IEC 9899 Standard.

This pragma can occur outside an external declaration or within a compound statement. When outside external declarations, the pragma takes effect from its occurrence until another STDC CX_LIMITED_RANGE pragma is encountered or until the end of the translation unit. When within a compound statement, the pragma takes effect from its occurrence until another STDC CX_LIMITED_RANGE pragma is encountered within a nested compound statement, or until the end of the compound statement.

If this pragma is used in any other context, the behavior is undefined. The default state is off.


Pragma STDC FP_CONTRACT

Syntax:

#pragma STDC FP_CONTRACT ON
#pragma STDC FP_CONTRACT OFF

Description:

This pragma tells the compiler whether or not it is permitted to contract expressions. Also see ISO/IEC 9899 Standard.

Each pragma can occur either outside external declarations or preceding all explicit declarations and statements inside a compound statement. When outside external declarations, the pragma takes effect from its occurrence until another FP_CONTRACT pragma is encountered, or until the end of the translation unit. When inside a compound statement, the pragma takes effect from its occurrence until another FP_CONTRACT pragma is encountered within a nested compound statement, or until the end of the compound statement. At the end of a compound statement, the state for the pragma is restored to its condition before the compound statement.

If this pragma is used in any other context, the behavior is undefined. The default state is on.


Pragma STDC FENV_ACCESS

Syntax:

#pragma STDC FENV_ACCESS ON
#pragma STDC FENV_ACCESS OFF

Description:

This pragma provides a means to inform the compiler when a program might access the floating point environment to test flags or run under non-default modes. Use of the pragma allows certain optimizations that could subvert flag tests and mode changes such as global common sub expression elimination, code motion, and constant folding.

The pragma can be placed either outside external declarations or preceding all explicit declarations and statements inside a compound statement. When outside external declarations, the pragma takes effect from its occurrence until another FENV_ACCESS pragma is encountered or until the end of the translation unit. When inside a compound statement, the pragma is in effect from its occurrence until another FENV_ACCESS pragma is encountered within the nested compound statement or until the end of the compound statement. At the end of a compound statement, the state for the pragma is restored to its condition just before the compound statement.

If the pragma is used in any other context, the behavior is undefined. If part of a program tests flags or runs under non-default mode settings but was translated with the state for the FENV_ACCESS pragma off, then the behavior of the program is undefined.

Also see ISO/IEC 9899 Standard.


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.

Both PA and Itanium(r)-based aCC support 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.

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