#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.
#pragma pragma-stringpragma-string can be one of the following instructions to the compiler with any required parameters.
Pragma OPTIMIZE |
#pragma OPTIMIZE ON #pragma OPTIMIZE OFF
Use this pragma to turn off optimization in sections of a source program.
NOTE:
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 |
#pragma OPT_LEVEL 1 #pragma OPT_LEVEL 2 #pragma OPT_LEVEL 3 #pragma OPT_LEVEL 4
OPT_LEVEL pragma sets the optimization level to
1, 2, 3, or 4.
NOTE:
OPT_LEVEL 3 and 4 are allowed only at the
beginning of a file.
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 |
#pragma hdr_stop
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.
#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.
#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();
Pragma HP_SHLIB_VERSION |
#pragma HP_SHLIB_VERSION ["]date["]The date argument is of the form month/year, optionally enclosed in quotes.
94
for 1994) or a full year specification (1994).
Two-digit year codes from 00 through 40 represent
the years 2000 through 2040, respectively.
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.
Pragma COPYRIGHT |
#pragma COPYRIGHT "string"string is the set of characters included in the copyright message in the object file.
If no date is specified (using pragma
COPYRIGHT_DATE), the current year
is used in the copyright message.
#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:
Pragma COPYRIGHT_DATE |
#pragma COPYRIGHT_DATE "string"string is a date string used by the COPYRIGHT pragma.
Use the COPYRIGHT pragma to put the copyright
message into the object file.
#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:
Pragma LOCALITY |
#pragma LOCALITY "string"string specifies a name to be used for a code subspace.
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.
#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 |
#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.
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
}
Refer also to Default Data Storage and Alignment.
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
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.
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.
allow_unaligned_data_access().
This causes every signal due to unaligned access to be intercepted
and handled as expected.
It also creates significant run-time overhead for every access to
unaligned data, but does not impact access to aligned data.
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 |
#pragma VERSIONID "string"string is a string of characters that HP aC++ places in the object file.
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 HP_NO_RELOCATION |
#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:
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.
This pragma is automatically supplied by HP aC++ for non-static member functions.
Pragma HP_LONG_RETURN |
#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:
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.
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.
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 HP_DEFINED_EXTERNAL |
#pragma HP_DEFINED_EXTERNAL name1[,name2,...nameN]
name1 through nameN are names of functions in shared libraries. Note that C++ mangled names are not supported.
Any named function:
Import stubs are code sequences generated at calls to shared library routines. The import stub queries the PLT (Procedure Linkage Table) to determine the address of the shared library function and calls it. The HP_DEFINED_EXTERNAL pragma inlines this import stub.
Unlike HP_NO_RELOCATION and HP_LONG_RETURN, HP_DEFINED_EXTERNAL is not automatically supplied by HP aC++.
Do not use the HP_DEFINED_EXTERNAL pragma at function definitions, only at function calls. Specifying it at function definitions will result in incorrect behavior.
On PA-RISC 1.1, use the HP_DEFINED_EXTERNAL pragma only when calling a shared library from an executable file. Using it on calls within an executable file will cause the program to abort.
If your function takes floating-point parameters, you should also use the HP_NO_RELOCATION pragma (if floating-point parameters are present).
You should also use the HP_LONG_RETURN pragma with the HP_DEFINED_EXTERNAL pragma. If you don't, the import stub may be too large to inline.
Use the HP_DEFINED_EXTERNAL pragma only on calls to functions in shared libraries. On PA-RISC 2.0, it will degrade performance of calls to any other functions.