Pragma Directives

You typically use a #pragma directive to control the actions of the compiler in a particular portion of a program without affecting the program 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 to the end of the compilation unit or until another pragma changes its status.

A #pragma directive is an instruction to the compiler and is ignored during preprocessing.

Syntax:

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

Pragma OPTIMIZE

Syntax:

#pragma OPTIMIZE ON 
#pragma OPTIMIZE OFF

Description:

Turns optimization on or off.

Use this pragma to turn off optimization in sections of a source program.

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 1
#pragma OPT_LEVEL 2
#pragma OPT_LEVEL 3
#pragma OPT_LEVEL 4

Description:

The OPT_LEVEL pragma sets the optimization level to 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 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:


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 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 1997, the directive

#pragma COPYRIGHT "Acme Software"

places the following string in the object code:

(C) Copyright Acme Software, 1997. 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-1997"
#pragma COPYRIGHT "Brand X Software"

place the following string in the object code:

(C) Copyright Brand X Software, 1990-1997. 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 LOCALITY

Syntax:

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

Description:

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. Code that is not headed by a LOCALITY pragma is associated with the name $CODE$.

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

Example:

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


Pragma pack

Syntax:

#pragma pack [n] 
Where n can equal 1, 2, 4, 8, or 16 and indicates, in bytes, the maximum alignment of class fields having non-class types. If n is not specified, maximum alignment is set to the default value.

Description:

This 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, 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, either of the following two options are available.

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 code not compiled with the +u1 option, consider the following example. Unless compiled with -DRECOVER on the command-line and linked with /usr/lib/libhppa.a, 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 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