search    
Hewlett-Packard
Choice of the C++ Runtime (-AA vs -AP) on HP-UX

HP supports two distinct runtime environments for C++ applications under HP-UX:

  1. Classic C++ runtime
  2. Standard C++ runtime

The Classic C++ runtime is based on the original IOstream library (as defined in the early implementations of C++ and originally included with cfront-based C++ compilers) and the initial version of the Standard Template Library in 1995.

The Standard C++ runtime is based on the final definition of the C++ library included in the ISO/ANSI C++ International Standard (ISO/IEC 14882:1998 - http://www.ncits.org/cplusplus.htm) published in late 1998.

Both the Classic and Standard C++ runtimes also include Rogue Wave's (http://www.roguewave.com/products/enterprise/) tools.h++ library. (tools.h++ 7.0.1 is included with the Classic C++ runtime and tools.h++ 7.1.1 with the Standard C++ runtime.)

The two C++ runtimes provide similar but not identical interfaces and functionality. In particular, since the final standard for the C++ language revised some of the interfaces (APIs) and introduced a number of new interfaces, the Standard runtime is not a superset of the Classic C++ runtime resulting in two disjoint and incompatible libraries. As a result of this, a C++ application needs to select one of these runtime libraries and must be consistently compiled and linked to run under one of the C++ runtimes.

Under aCC, the HP C++ compiler, the -AA option selects the Standard C++ runtime and -AP chooses the Classic C++ library (and runtime).

The Classic C++ runtime is provided for forward compatibility with the large number of C++ applications that were developed before the final standard for the C++ was developed and published; while the Standard C++ runtime is necessary for building and running portable and standard-conforming applications.

This section discusses the following topics:
Building C++ Applications or Libraries for HP-UX

Since a C++ application can include (and run under) only one of the C++ runtimes, when building an application or a shared library that contains any C++ components:

  • All C++-containing source files in the application must be compiled using the same -AA or -AP options (or consistently use the compiler's default for the C++ runtime.)
  • The application or shared library must be linked using the C++ compiler (aCC), and specifying the same -AA or -AP option used in compiling the C++-containing components.
  • Any 3rd party C++-based libraries that are used (statically or dynamically linked or dynamically loaded) with a C++ application or library must also have been delivered for the same (Classic or Standard) C++ runtime as the application or the library.

The most common symptom of not following the above rules is link time error when names required from one or the other runtime are not resolved (unsatisfied symbol references). But for an application that makes minimal explicit use of the C++ runtime, it is also possible to see it successfully link but fail to run as expected.

Determining which Runtime an Object File, Library or App. Depends on

Since the Standard C++ runtime requires that the library names to be in namespace std; the string namespace is present in the compilation dictionary of files produced with the -AA option.

On ItaniumŪ-based systems, the following command can be used to determine if a file is compiled for the Standard C++ runtime.

elfdump -dc <object-lib-or-executable-name> | fgrep "test namespace" 

Empty result from this command implies that the file depends on the Classic C++ runtime if the source contained any C++ constructs.

On PA-RISC systems, the following commands can be used to determine if a file is compiled for the Standard C++ runtime:

For PA32:

odump -comp <object-lib-or-executable-name> | fgrep "test namespace" 

For PA64:

elfdump -dc <object-lib-or-executable-name> | fgrep "test namespace"

If a shared library or an executable (application) was incorrectly built such that it simultaneously depends on both C++ runtimes (that is, it would have undefined behavior if run), it can be recognized by:

-AP
For PA-RISC systems:
ldd <shared-lib-or-executable-name> | fgrep -e libstream. -e libstd. -e librwtool. -e libCsup.

For Itanium-based systems:
ldd <shared-lib-or-executable-name> | fgrep -e libstream. -e libstd. -e librwtool.

-AA
ldd <shared-lib-or-executable-name> | fgrep -e _v2.

Using the above commands, you can determine if a shared library or executable file (<shared-lib-or-executable-name>) has been built incorrectly. Follow these steps:

  1. Pick the appropriate command (PA-RISC or Itanium-based) from the -AP part.
  2. Then pick the one from the -AA part.
  3. If the file has output for both -AP and -AA, then it is incorrectly built.
Which C++ Runtime Should I be Using?

To maintain forward compatibility for existing applications (and build systems) on PA-RISC under HP-UX 11.0 and 11.11, the HP C++ compiler for this platform defaults to the Classic C++ runtime. Use the -AA option on these systems if your application is to be deployed in the Standard C++ runtime.

On the Itanium-based systems running HP-UX 11.22 and 11.23, since a recompile is necessary for native mode of applications that are migrating from previous versions of HP-UX to this platform, the HP C++ compiler defaults to the Standard C++ runtime. This is to facilitate migration of standard conforming (portable) C++ applications to Itanium-based platform and provide maximum run time compatibility for C++ library providers. But the -AP option is also supported to allow forward source compatibility.

  • For ISVs who ship C++ libraries in binary form, on HP-UX 11.20 or higher (the Itanium-based platform) we recommend that they build and support their library for the Standard C++ runtime, (that is, use the HP compiler's default).
  • On the PA-RISC platform (HP-UX 11.0 and 11.11) we expect ISVs to continue to ship their libraries for the C++ runtime they have been supporting so far (that is, backward compatibility) but, over time, we recommend ISVs to also make (a version 2 of) the library available for the Standard C++ runtime.
  • For end users with no 3rd party C++ dependency, use the C++ runtime (header files) that is source compatible with your current source base. But over time, if the application currently depends on the classic C++ runtime (and headers), update the source code, over time, to build in the -AA mode and to run under the Standard C++ runtime. (This results in a more portable and better maintained code.) Legacy code that does not have a dependency on any 3rd part C++ library can continue to build and ship using -AP since the Classic C++ runtime continues to be supported on HP-UX 11.x.
  • Likewise, for end users who do depend on 3rd party libraries, if these libraries do not depend on the Standard C++ libraries, we recommend that the users migrate to the use of -AA mode, unless the 3rd party library requires them to stay with the Classic C++ library (default or -AP mode.)
Porting Applications Using Classic C++ Runtime to Standard C++ Runtime

Since the Standard C++ runtime is essentially built on top of the standard-conforming (ISO/ANSI) C++ library and this library makes heavy use of Generic Programming (templates), the header files used by the compiler with the -AA option (Standard C++ runtime) are substantially larger than the corresponding header files in the Classic C++ runtime (and used when compiling with the -AP option). As a result, it is possible to see a slow down in the application build time or slower runtime for applications that spend most of their times in the C++ I/O library.

The compiler automatically adds the following include paths and libraries to the command line when -AA option is used:

  • -I/opt/aCC/include_std
  • -lstd_v2
  • -lCsup_v2 (PA systems only)


IOstream Headers

The following is a list of header files mapping:

  • <iostream.h> maps to <iostream>
  • <fstream.h> maps to <fstream> and optionally <iostream>
  • <strstream.h> maps to <strstream>
  • <iomanip.h> maps to <iomanip>


Note: The new header file <iosfwd> can be used if just the declaration of ostream and istream are needed and not the specific insertion and extraction operators. This would replace the cases where the following are used:
class ostream;                       // replace by #include <iosfwd>
ostream& operator<<(ostream&, foo);  // change based on Source Mapping (see below)


Source Mapping

Do one (or more) of the following. These changes apply to both, the IOstream headers, and the container headers.

  1. Add the following using directive. This will work for -AA or -AP.
    namespace std {} using namespace std;
    cout << "hi guy" << endl;
    
  2. Add specific using declarations. This only works for -AA.
    using std::cout;
    using std::endl;
    cout << "hi guy" << endl;
    
  3. Add std:: before each symbol. This only works for -AA.
    std::cout << "hi guy" << std::endl;
    
List of HP-UX C++ Libraries and their Runtime Requirements

The following is a list of HP-UX C++ libraries an their runtime requirements on Itanium-based and PA-RISC systems.


HP Itanium-based Systems

On HP Itanium-based systems (HP-UX 11.22 and 11.23), the following libraries are available for the Standard C++ runtime. Any application that depends on these libraries, must likewise be built for the same library using -AA option, or the Itanium-based C++ compiler's default option.

  • HP TeMIP <-L ..., -l...>
  • HP WebM <-L ..., -l...>
  • HP JVM 1.4 <-L ..., -l...>
  • RogueWave SourcePro <-L ..., -l...>
  • IONA Orbix
  • BEA

The JavaTM libraries built with C++ are:

  • 32-bit:
    • <java_root>/jre/lib/IA64N/libfontmanager.so
    • <java_root>/jre/lib/IA64N/server/libjvm.so
  • 64-bit:
    • <java_root>/jre/lib/IA64W/libfontmanager.so
    • <java_root>/jre/lib/IA64W/server/libjvm.so

The Java libraries built with aCC on Itanium-based systems use the default Standard C++ runtime (-AA). Any C++ application that depends on these libraries must be built using the Standard C++ runtime (-AA option), which is the default on HP Itanium-based systems.

No Java libraries are provided for the Classic C++ runtime on HP Itanium-based systems.


HP PA-RISC Systems

On HP PA-RISC systems (HP-UX 11.0 and 11.11), the following libraries are available for the Classic C++ runtime:

  • HP WebM <-L ..., -l...>
  • HP JVM 1.4 <-L ..., -l...>
  • IONA Orbix
  • BEA

The Java libraries built with C++ are:

  • PA-RISC 1.1 32-bit:
    • <java_root>/jre/lib/PA_RISC/libfontmanager.sl
    • <java_root>/jre/lib/PA_RISC/server/libjvm.sl

  • PA-RISC 2.0 32-bit:
    • <java_root>/jre/lib/PA_RISC2.0/libfontmanager.sl
    • <java_root>/jre/lib/PA_RISC2.0/server/libjvm.sl

  • PA-RISC 2.0 64-bit:
    • <java_root>/jre/lib/PA_RISC2.0W/libfontmanager.sl
    • <java_root>/jre/lib/PA_RISC2.0W/server/libjvm.sl

The JavaTM libraries built with aCC on PA-RISC use the default Classic C++ runtime (-AP). Any C++ application that depends on these libraries must be built using the Classic C++ runtime (-AP option), which is the default on HP PA-RISC.

No JavaTM libraries are provided for the Standard C++ runtime on HP PA-RISC at this time, but libraries supporting the Standard C++ runtime will be provided in a future 1.4.1.0x and 1.4.2.0x release.

For more information, refer to the J2SE SDK Release Notes.

Frequently Asked Questions

In December 2000, HP released the aCC A.03.26 compiler, which introduced a new, standard compliant, C++ runtime library in addition to the Classic C++ runtime that consisted of the original IOstream and STL libraries. The -AA option was introduced to explicitly select the Standard C++ runtime and the default (-AP option) would use the Classic C++ runtime.

Since the Standard C++ library had changed a number of APIs present in the old library, in addition to introducing new APIs, the Classic and Standard libraries are incompatible - both cannot be present when building or running a given application. The HP PA-RISC C++ compiler continues to default to the Classic C++ runtime to retain compatibility with the existing build systems and makefiles.

Since moving applications to HP's new Itanium-based HP-UX 11i v1.6 and 11i v2.0 operating systems requires these applications to be recompiled (except when using the PA-RISC emulation mode to run PA binaries on Itanium-based hosts), the default C++ runtime on these operating systems is the new Standard C++ library.

The following is a list of most frequently asked questions:

  1. Basic -AA & -AP compatibility questions:

    1. Are they still binary incompatible if I do not use C++ features?
    2. Are they still binary incompatible if they are shared libraries?
    3. What if I have a shared library built with -AA that does not have any C++ constructs in the interface?
    4. Can I specify /opt/aCC/include on the command line while using -AA?
    5. Do I have to link with the same option I compile with?
    6. What are the standard C++ libraries I need to specify while linking with -AA option?
  2. How can I compile std namespace usage without using -AA, so that I can maintain binary compatibility with 3rd party libraries?
  3. Is PCH (precompiled header feature) supported with -AA?
  4. How can I determine if a library has been compiled with one or the other?
  5. My product is a C++ library used by my customers to build their applications. Do I need to provide separate libraries compiled both ways?
  6. What are the performance implications of -AA versus -AP? What is the characteristic of an application that can cause performance degradation?
  7. I have heard that -AA is the default on Itanium-based systems/platforms. Do I have to migrate my sources to -AA?
  8. What is the issue with for() loops? What is the difference between the ItaniumŪ default and using an explicit -AA option?
  9. Why is there a different default on Itanium than on PA-RISC?
  10. How do I change my sources to migrate them to -AA?
  11. Can I write code that works for both?
  12. How can I check within the code if -AA is used?
  13. Is -AA ever going to become the default on PA-RISC?
  14. Does HP use -AA?
  15. My application is dependent on Java, but HP does not provide a Java JVM built with -AA. How can I migrate to Itanium?
  16. My application uses two separate library packages; one of which is only available in -AP mode (because the vendor went out of business) and the other is only available in -AA mode. What can I do?
  17. What does it look like when I get this wrong?
  18. If I dynamically load a shared library compiled with the opposite option from the rest of my process, what error message do I get?
  19. Is the HP supplied Rogue Wave Tools.h++ library usable with -AA option?
  20. Is it safe to accept the compiler's automatic changing of <iostream.h> into <iostream> followed by using namespace std?
  21. I had sourced classic STL from RogueWave directly, and it is part of my source tree. What is the implication of using -AA?
  22. I use STLPort sources. What is the implication of using -AA?
  23. I am using STLPort. After I started using -AA, I get compilation errors that strstr, strrchr, etc. are not found. Why?

1a. Are they still binary incompatible if I do not use C++ features?

If you build using -Ae (C mode) there is no incompatibility.

back


1b. Are they still binary incompatible if they are shared libraries?

Yes. You cannot mix -AA or -AP in any way, shape or form.

back


1c. What if I have a shared library built with -AA that does not have any C++ constructs in the interface?

Using any C++ constructs that use the aC++ runtime will also cause the conflict.

back


1d. Can I specify /opt/aCC/include on the command line while using -AA?

No. You should leave it to the compiler to select the default directories.

Also, do not use /opt/aCC/include_std with -AP.

back


1e. Do I have to link with the same option I compile with?

Yes

back


1f. What are the standard C++ libraries I need to specify while linking with -AA option?

The C++ language requires that nonlocal static objects be initialized before any function or object is used. HP aC++ automatically initializes nonlocal static objects in all object files, including shared libraries, before the first statement in main() executes. No special files or link options are needed.

If the library is being dynamically loaded from pure C or Java as a plugin, the library should be linked with the HP aC++ runtime libraries in the following order:

-AP: -lstd -lstream -lCsup_v2 -lm 
-AA: -lstd_v2 -lCsup_v2 -lm

If the library does not use libstd (STL) or libstream (iostreams), then they can be eliminated. If tools.h++ is used, then add -lrwtool (or -lrwtool_v2) to the left.

back


2. How can I compile std namespace usage without using -AA, so that I can maintain binary compatibility with 3rd party libraries?

You cannot compile std namespace without using the old libraries (even by somehow removing that namespace). If you use #define std or -Dstd=, you can make most of stds go away and the -AP option may work. However, you need to change iostream back to iostream.h.

You can also inject types into the std namespace so you do not have to change the majority of your code:

#include <string>
namespace std {
   using ::string;
}
   std::string s("hi guy");

back


3. Is PCH (precompiled header feature) supported with -AA?

Yes. Starting from A.03.50, aCC supports PCH with -AA.

back


4. How can I determine if a library has been compiled with one or the other?

Look at the unsatisfied symbol references. You will see std:: in the demangled names. (Except for Itanium-based platforms, if defined in libCsup.) You can also use odump -comp or elfdump -dc options and look for "-test namespaces".

Also, look at the dependent shared library list. You can use ldd(1) or chatr(1) to see the shared lib dependency lists. odump -sllibloadlist (PA 32) will do it recursively.

If you see _v2, it is -AA. If you see libstream, it is -AP.

back


5. My product is a C++ library used by my customers to build their applications. Do I need to provide separate libraries compiled both ways?

Yes. Otherwise you restrict your customers to only -AA or -AP. If your library is really C code, compile it with the cc compiler (or the aCC -Ae option) and it will be compatible with either -AA or -AP C++ code.

back


6. What are the performance implications of -AA versus -AP? What is the characteristic of an application that can cause performance degradation?

Standard iostreams that will be used with -AA are quite slow compared to classic iostreams (with -AP). Standard iostream is slower to compile. Performance depends on the application and exactly what is being read/written. Some issues (like append access over NFS) have been fixed.

Performance also depends on how much time is spent doing C++ I/O versus other work. One important point is that the application must be optimized since the templatized code is now in the application. Other factors that can significantly affect performance are threading and using locales.

back


7. I have heard that -AA is the default on ItaniumŪ-based systems/platforms. Do I have to migrate my sources to -AA?

The default on ItaniumŪ-based systems/platforms is -AA with -ansi_for_scope,off. HP advises all ISVs to compile with -AA. You need to migrate your sources to -AA if you expect to interoperate with other ISVs that support only -AA.

back


8. What is the issue with for() loops? What is the difference between the ItaniumŪ default and using an explicit -AA option?

The Itanium default is not strictly ANSI-standard compliant; omitting the ANSI rule for scope of variables declared in for() loops. This difference is closed by the -ansi_for_scope,on option that is included in the -AA option, but not the Itanium default.

Always specify -AA to be explicit.


Note: This for-scoping functionality can be used with -AP by adding -Aa.

back


9. Why is there a different default on Itanium than on PA-RISC?

Over time, more and more ISVs and customers required -AA functionality. They could not use it because not all PA ISVs provided their libraries also compiled with -AA. For compatibility reasons, on PA, the default is kept as -AP On Itanium, all ISVs are asked to recompile, so there is opportunity to switch to the new -AA standard.

back


10. How do I change my sources to migrate them to -AA?

Compile with -AA and fix all the errors. Some of the compilation errors could be because of the removal of some of the iostream header files.

Some of the cfront iostream functionality has been removed. The removed functionality will show up as errors at compile time. Below is a list of missing cfront compatible iostream functions when -AA is used:

fstream:
Missing enums nocreate & noreplace

detach()
ios::ate slightly different, may truncate.

ios:
Missing enum stdio

unsetf() returns void

istream:
Missing get(unsigned char&)

manip:
major differences if not using predefined manipulations.
You must implement your own non-standard manipulators.

ostream:
<< void*, different format

sbuf.prot:
dbp() missing
Reserve area missing from ANSI

setb() not in ANSI.
sbuf.pub:
out_waiting() not in ANSI.
stossc() same as sbumpc.

ssbuf:
strstreambuf constructor for alloc/delete
takes a size_t, not long.

stdiobuf:
class missing.

back


11. Can I write code that works for both?

Yes. Only with conditional compilation. And/or by using the following:

namespace std:: construct:
namespace std {} using namespace std;

You can put this construct anywhere, as many times as you like. Or once at the beginning - as long it is before you reference any symbol that does not have the needed std::. And you can use it with -AP too.

back


12. How can I check within the code if -AA is used?

The macro _HP_NAMESPACE_STD is defined by the compiler if -AA is used. This macro can be tested by #ifdef _HP_NAMESPACE_STD.

back


13. Is -AA ever going to become the default on PA-RISC?

For compatibility reasons, on PA-RISC, aCC will continue to have -AP as default. There is no plan of changing the default as of now.

back


14. Does HP use -AA?

This option is used in a lot of products on Itanium-based systems. It is used in TeMIP (Telecommunication Management Information Platform) on PA and on WBEM (Web-Based Enterprise Management).

back


15. My application is dependent on Java, but HP does not provide a Java JVM built with -AA. How can I migrate to Itanium?

Starting from versions 1.3.1.10 and 1.4.1.03, Java is -AP/-AA agnostic. For Itanium-based systems, it works fine (since there is only one libCsup). For PA, you need to select libCsup (or libCsup_v2) by setting SHLIB_PATH.

For more information, refer to the SDK Release Notes at the following URLs:

back


16. My application uses two separate library packages; one of which is only available in -AP mode (because the vendor went out of business) and the other is only available in -AA mode. What can I do?

There are not many options. You will need to get a -AA built library, or you can probably split the application into multiple processes; one -AA, and one -AP.

back


17. What does it look like when I get this wrong?

Once you get past the compile-time errors, the next step is likely to be unsatisfied symbol references at link time. After fixing those, if you attempt to use both sets of runtime libraries, there may be runtime problems.

back


18. If I dynamically load a shared library compiled with the opposite option from the rest of my process, what error message do I get?

Again, mostly likely, unsatisfied symbol references. Or other runtime aborts and maybe silent data corruption.

back


19. Is the HP supplied Rogue Wave Tools.h++ library usable with -AA option?

Only RogueWave Tools.h++ library 7.1.1 (librwtool_v2) is usable with -AA option. RogueWave Tools.h++ library 7.0.6 (librwtool) cannot be used with -AA.

back


20. Is it safe to accept the compiler's automatic changing of <iostream.h> into <iostream> followed by using namespace std?

It is recommended that you change all <iostream.h> to <iostream>. Allowing an all inclusive using namespace std will lead to some name clashes as described in the questions below.

back


21. I had sourced classic STL from RogueWave directly, and it is part of my source tree. What is the implication of using -AA?

Since -AA will result in the inclusion of namespace std wrapped STL classes or functions, there should not be a clash. But introduction of an all inclusive using namespace std should be avoided as it will lead to name clashes. (Do not let the compiler change iostream.h to <iostream> followed by using namespace std, by changing your sources as described in the previous question).

back


22. I use STLPort sources. What is the implication of using -AA?

Because STLPort always had std namespaces, it is possible that mixing aCC's classic STL with STLPort worked under -AP. With -AA there is likely to be a namespace clash. The +nostl option is recommended with -AA to ensure that only STLPort is in use.

back


23. I am using STLPort. After I started using -AA, I get compilation errors that strstr, strrchr, etc. are not found. Why?

This could be because <cstring> has been inconsistently included from STLPort/aCC. The <cstring> in /opt/aCC/include_std/ has implementations for strpbrk, strstr, strchr, strrchr, and memchr as inline functions. /usr/include/string.h will not declare them if -AA has been used.

back