search    
HP aC++ Online Programmer's Guide
Hewlett-Packard
Migrating from HP C++ (cfront) to HP aC++

This section discusses differences in syntax and functionality that you need to consider when migrating from HP C++ (cfront) to HP aC++.

It discusses the following topics:

For more information, refer to the HP aC++ Transition Guide available at http://www.hp.com/dspp/

General Guidelines for Migration

Because of incompatibilities in areas such as name mangling, libraries, and object layout, all of your C++ code for an application or library must be compiled and linked with either HP C++ (cfront) or with HP aC++. You cannot mix object files compiled with HP C++ (cfront) with those compiled with HP aC++.

This section discusses the following general guidelines when migrating from HP C++ (cfront) to HP aC++:


Getting Started with Migration

Complete the following procedure to migrate your code from HP C++ (cfront) to HP aC++:

  1. Compile your code with the HP C++ (cfront) compiler using the +p option. This option requests the compiler to treat anachronistic constructs as errors. Fix the anachronisms.
    For example:
    CC +p cfrontfile.C
  2. In your Makefiles:
    • Change CC to aCC.
    • Set the path to /opt/aCC/bin.
    • Review command-line options and change when necessary.
  3. Compile and fix syntax errors.
    • Note that cfront-generated object code and libraries are not compatible with those produced by aCC.
    • If your program uses operator new, allow for memory allocation exceptions that may occur. Modify your cfront code to handle memory allocation failures to avoid a program abort.
  4. Make library changes. Begin migration to the Standard C++ Library and Tools.h++ Library.
  5. Make template changes.
    • If a program or library uses templates, consider source code changes that may be required to direct template instantiation.
    • Use the +inst_directed option with the initial compilation to defer consideration of compile-time errors due to template instantiation

Writing Code for both Compilers

Use the __cplusplus macro (defined by the draft standard) to write code that can be compiled by both HP C++ and HP aC++.

Example:


#if __cplusplus >= 199707L

// HP aC++ code

#else

// HP C++ code

#endif // __cplusplus >= 199707L


Explicit Loading and Unloading of Shared Libraries

HP aC++ uses system calls rather than C++ function calls to explicitly load and unload shared libraries. When migrating to HP aC++, make the following source code changes:

  • Change cxxshl_load() to shl_load().
  • Change cxxshl_unload() to shl_unload().
  • Change #include to #include <dl.h>.

Command-Line Differences

In HP aC++, you invoke the compiler with the aCC command instead of the CC command used to invoke HP C++.

The following sections describe differences in command-line options:


New Command-Line Options

The following table describes the new options for HP aC++. These options are not available for HP C++ (cfront). However, if a related option exists, it is noted here.

Option Description
-g0 Replaces the -g debugger option. It generates complete debug information for the debugger.
+help Invokes the HP aC++ Online Programmer’s Guide.
+noeh

Disables exception handling. In HP aC++, exception handling is enabled by default.

Note that in HP C++ (cfront), exception handling is off by default. To turn it on, you must use the +eh option which is obsolete in HP aC++.

Precompiled Header File Options Reduces compilation time and executable file size by precompiling common include (header) files.
Template Options

There are new options and new functionality for template processing. For more information, see Using HP aC++ Templates


Obsolete Command-Line Options

The following table describes obsolete command-line options for HP aC++.

Option Description
Debugging Option
-y In HP C++ (cfront), the -y option generates a Static Analysis database if SoftBench is installed and /opt/softbench/bin is at the beginning of your path. The option is not required in HP aC++.
Exception Handling Option
+eh

Enables exception handling in HP C++.

In HP aC++, exception handling is enabled by default. To disable exception handling off, compile with the +noeh option.

Library Option
-depth

In HP C++, this option instructs runtime system to traverse the shared library list in a depth-first manner when calling static constructors and when loading the libraries. The default is to traverse the shared libraries in a left-to-right order when calling static constructors. The order of execution of static constructors within each shared library is not affected by this option.

In HP aC++, -depth functionality is the default option.

Null Pointer Option
-Z

Allows dereferencing of null pointers at run time. The value returned from a dereferenced null pointer is zero. This is the default behavior for HP C++ (cfront) and for HP aC++.

Preprocessor Options
-Ac

Requests the compatibility mode HP C++ preprocessor, cpp. This option is not available in HP aC++.

-C

Prevents the preprocessor from stripping comments from your source file. In HP aC++ comments are retained.

-Wp

The -W option no longer accepts p as a subprocess parameter. In HP aC++, there is no separate subprocess for the preprocessor.

Use the CC command (HP C++) as a workaround:

Example:
CC prog.C -I /opt/aCC/include -I /opt/aCC/include/iostream -I /usr -I /usr/include

See Migration Considerations Related to Preprocessing and Preprocessing in HP aC++ for more information.

Template Options
-pta Instantiates all members of used template classes and all needed template functions.
-ptb Invokes ld instead of nm to do simulated linking.
-pth Uses short file names for template instantiation files.
-ptH"list" Specifies file name extensions for template declaration files (header files).
-ptn Instantiates at link time rather than at compile time.
-ptrpath Specifies an alternate location for the template repository.
-pts Splits template instantiations into separate object files.
-ptS"list" Specifies file name extensions for template definition files.
-ptv Provides verbose information about template processing. For HP aC++, use the +inst v option.
Translator Mode Options
+a0 Causes the translator to produce Classic C style declarations.
+a1 Causes the translator to produce ANSI C style declarations.
-F Runs only the preprocessor and translator, and sends the resulting source code to standard output (stdout).
-Fc Similar to the -F option, except that C source code is generated.
+i Generates an intermediate C language source file that has the file name suffix ..c in the current directory.
+m Provides maximum compatibility with the USL C++ implementation.
+Rnumber Promotes only first number register variables to the register class.
+T Requests translator mode.
+xfile Reads a file of data types, sizes, and alignments that the compiler uses when generating code.
Virtual Table Options
+e0 Causes virtual tables to be external and defined elsewhere, that is, uninitialized.
+e1 Causes virtual tables to be declared externally and defined in a given module, that is initialized.


Changed Command-Line Options

Functionality for the following options is different for HP C++ (cfront) than it is for HP aC++. The following table describes the obsolete command-line options for HP aC++.

Option Description
-E Runs the preprocessor only on named C++ files, not on assembly files, and sends the result to standard output (stdout).
-g

Generates minimal information for the debugger (as does the -g1 option). This is the default option. The -g0 option replaces -g and generates complete debug information for the debugger.

See Debugging Options for more information.

-tx,name

The following values for x are related to translator mode and template subprocesses and are not supported in HP aC++.

  • 0 (zero) - C compiler
  • c - C compiler
  • i - Link-time template processor, c++ptlink
  • m - merge tool, c++merge
  • p - preprocessor
  • P - patch tool, c++patch
  • r - Compile-time template processor, c++ptcomp
-Wx,args

The following values for x are related to translator mode and template subprocesses and are not supported in HP aC++.

  • 0 (zero) - C compiler
  • c - C compiler
  • i - Link-time template processor, c++ptlink
  • m - merge tool, c++merge
  • p - preprocessor
  • P - patch tool, c++patch
  • r - Compile-time template processor, c++ptcomp

Compiler Coexistence
The HP C++ and HP aC++ compilers execute independently and can be installed on a single system.

HP C++ is located at:

/opt/CC

HP aC++ is located at:

/opt/aCC
Migration Considerations when Debugging

The HP/DDE Debugger supports HP aC++. The HP Symbolic Debugger, xdb, is not supported. Functionality of the -g debugger option has changed. It now generates minimal information for the debugger as does the -g1 option. This is the default.

The -g0 option replaces the -g option and generates full debug information for the debugger.

See Debugging Options for complete information.

HP aC++ Messages

As you migrate your code from HP C++ to HP aC++, you are likely to see many error and warning messages related to standards based syntax.

It may be helpful to compile using HP C++ (cfront) with the +p option. Then when the compiler encounters a standards based reserved word that is used as an identifier, it generates a warning message indicating that this syntax will cause an error in HP aC++.


Interpreting HP aC++ Messages

The aC++ compiler can issue a large variety of diagnostics in response to unexpected situations or suspicious constructs. These diagnostics are classified below. For more information, see
aCC Message Catalog if you are on a machine where the compiler is installed. The location of the catalog is:

/opt/aCC/lib/nls/msg/C/aCC.msgs
Command Errors
These are issued when the command line is not correctly formed and the compiler cannot proceed with compilation.
Command Warnings
These sometimes occur when an option is not recognized, but compilation proceeds without that option.
Fatal Errors
These are issued for ill formed programs for which the compiler cannot recover reliably. Syntax errors usually fall into this category. No object file will be generated if such an error is encountered.
Future Errors
These are actually serious warnings indicating that a language rule was violated, but the compiler will continue generating code. These warnings can be turned into hard errors by using the +p option (pedantic mode).
Anachronisms
These warnings also diagnose ISO/ANSI C++ language violations. Code that triggers this sort of diagnostic was considered legal in the past.
Warning
These help in identifying possible sources of bugs, often because the code triggers behavior that is not precisely defined by the C++ standard.
Suggestion/Informational
These diagnostics are not emitted unless the -w option is provided. In that case, the compiler attempts to identify more suspicious constructs.
Tool Errors
Very rarely, aC++ may fail in a component that is not specific to the C++ language (e.g., the PA-RISC optimizer); in that case, a Tool Error is emitted. The compilation process cannot recover from these, and they are often a sign of a defect in the compiler.

Frequently Encountered Messages

Frequently encountered diagnostic message numbers are listed and described in the HP aC++ Transition Guide at the following URL:

http://h21007.www2.hp.com/dspp/tech/tech_TechDocumentDetailPage_IDX/1,1701,1744,00.html
 

Migration Considerations when Using Exception Handling

When migrating exception handling code, the following characteristics of HP aC++ differ from those of HP C++ (cfront):


Exception Handling is the Default

In HP aC++ exception handling is enabled by default. Use the +noeh option to disable exception handling.

With exception handling disabled, the keywords throw and try generate a compiler error. The HP C++ (cfront) compiler, behaves differently; the default is exception handling off. To turn it on, you must use the +eh option.

If your executable throws no exceptions, object files compiled with and without the +noeh option can be mixed freely. However, in an executable that throws exceptions (HP aC++ runtime libraries throw exceptions), you must be certain that no exception is thrown in your application which will unwind through a function compiled without the exception handling option turned on.

In order to prevent this, the call graph for the program must never have calls from functions compiled without exception handling to functions compiled with exception handling (either direct calls or calls made through a callback mechanism). If such calls do exist, and an exception is thrown, the unwinding can cause:

  • non-destruction of local objects (including compiler generated temporaries)
  • memory leaks when destructors are not executed
  • runtime errors when no catch clause is found


Memory Allocation Failure and operator new

In HP aC++ programs, when either operator new ( ) or operator new [ ] cannot obtain a block of storage, a bad_alloc exception results. This is required by the ANSI/ISO C++ International Standard.

In HP C++, memory allocation failures return a null pointer (zero) to the caller of operator new ().

To handle memory allocation failures in HP aC++ and to avoid a program abort, do one of the following:

  • Write try or catch clauses to handle the bad_alloc exception.
  • Use the nothrow_t parameter to specify the type when calling operator new and check for a null pointer.
Example:

operator new (size_t size, const nothrow_t &) throw();

operator new [] (size_t size, const nothrow_t &) throw();

    .

    .

    .

#include 

#include 



class X{};



void foo1() {

 X* xp1 = new(nothrow())X;   // returns 0 when creating a nothrow

                             // object, if space is not allocated

}



void foo2() {

 X* xp2 = newX:              // may throw bad_alloc

}



void main() {

  try {

    foo1();

    foo2();

  }



  catch (bad_alloc) {

    // code to handle bad_alloc

  }

  catch(...) {

    // code to handle all other exceptions

  }

}


Possible Differences when Exiting a Signal Handler

Behavior when exiting a signal handler through a throw may differ between the two compilers.

In HP aC++, a try block begins following the first call after the try keyword. This conforms to the standard that a legal exception cannot be thrown prior to the first call. The current handlers of try block are considered candidates to catch the exception.

In HP C++, the try keyword defines the beginning of a try block.

In this situation, when a signal is taken while executing between the try keyword and the return point of the first call, a throw from the signal handler does not find the associated handlers as candidates for catching the exception.


Differences in setjmp/longjmp Behavior

Interoperability with setjmp/longjmp is not implemented.

The standard specifies that an implementation need not clean up objects whose lifetimes are shortened by a longjmp:.

The function signature longjmp(jmp_buf jbuf, int val) has more restricted behavior in this International Standard. When automatic objects are destroyed by a thrown exception, transferring control to a destination point in the program, a call to longjmp(jbuf, val) at the throw point transfers control to the destination point results in undefined behavior.


Calling unexpected

Unlike HP C++, in HP aC++, when an unexpected handler wants to exit through a throw, it must throw an exception that is legal according to the exception specification that calls unexpected(), unless that exception specification includes the predefined type bad_exception. If it includes bad_exception, and the type thrown from the unexpected handler is not in the exception specification, then the thrown object is replaced by a bad_exception object and throw processing continues.

The following example is legal in HP C++ but not in HP aC++. You can make the example legal by including the exception header and adding bad_exception to foo’s throw specification. The catch(...) in main will then catch a bad_exception object. This is the only legal way an unexpected-handler can rethrow the original exception.


//     #include <exception<  Needed to make the example legal.



void my_unexpected_handler() { throw; }



void foo() throw() {



//     void foo() throw(bad_exception) {   To make the example legal,

//                                         replace the previous line

//                                         of code with this line.



   throw 1000;

}



int main() {

   set_unexpected( my_unexpected_handler );

   try {

   foo();

   }

catch(...) {

   printf("fail - not legal in aCC\n");

   }

return 0;

}

Following is an example, illegal because my_unexpected_handler rethrows an int. A possible conversion is to throw &x instead, as this is a pointer to int and therefore legal with respect to the original throw specification. Alternatively, you can add bad_exception to the throw specification, as in the prior example.


int x = 1000;



void my_unexpected_handler() { throw; }



void foo() throw( int * ) {

   throw 1000;

}



int main() {

   set_unexpected( my_unexpected_handler );

try {

   foo();

}

catch(...) {

   printf("fail - not legal in aCC\n");

}

return 0;

}


Unreachable catch Clauses

Unreachable catch clauses are diagnosed by HP C++ but not by HP aC++. For example,


class C {

// ...

};



class D : public C {

// ...

};



...



catch(C) {

}

catch(D) {          // Unreachable since previous catch masks this one.

                    // Throw of D will be caught by catch for base class.

}



catch(C * ) {

}

catch(D * ) {       // Unreachable since previous catch masks this one.

                    // Throw of D * will be caught by catch for pointer

                    // to base class.)

}


Throwing an Object having an Ambiguous Base Class

HP C++ generates an object throw error that has an ambiguous base class. In HP aC++, a throw of an object having an ambiguous base class is not caught by a handler for that base, since that would involve a prohibited derived-to-base conversion.

In the following example, the throws are caught by the handlers for D1 and D1*, respectively. The handlers for C are disqualified because C is an ambiguous base class of E:


extern "C" int printf(char*,...);



class C {

public:

C() {};

};



class D1 : public C {

public:

D1() {};

};



class D2 : public C {

public:

D2() {};

};



class E: public D1, public D2 {

public:

E() {};

};



int main() {

E e;

try {

throw e;

}

catch(C) {

printf("caught a C object\n");

}

catch(D1) {

printf("caught a D1 object\n");

}

catch(D2) {

printf("caught a D2 object\n");

}

catch(E) {

printf("caught an E object\n");

}



try {

throw & e;

}

catch(C*) {

printf("caught ptr to C object\n");

}

catch(D1*) {

printf("caught ptr to D1 object\n");

}

catch(D2*) {

printf("caught ptr to D2 object\n");

}

catch(E*) {

printf("caught ptr to E object\n");

}

return 0;

}

Migration Considerations when Using Libraries
The following sections contain information about library migration from HP C++ (cfront) to HP aC++.
Standards Based Libraries

HP aC++ provides the following libraries that are not part of the HP C++ (cfront) compiler:

HP recommends that you use these standards based libraries whenever possible, instead of the cfront compatibility libraries.

See Creating and Using Libraries for more information.


HP C++ (cfront) Compatibility Libraries

HP aC++ provides the following libraries, whose functionality is part of the HP C++ (cfront) compiler. These libraries are not Standards based.


Run-time Support Library

The following HP aC++ libraries replace the cfront based HP C++ libraries:

  • /opt/aCC/lib/libCsup.sl -- shared version, the default
  • /opt/aCC/lib/libCsup.a -- archive version

Since the K & R float to double promotion rule is not supported, no equivalents to libC and libC.ansi are available.

HP C++ 10.x Stream Library File Locations (default version, without exception handling)

  • /usr/lib/libC.a
  • /usr/lib/libC.sl
  • /usr/lib/libC.ansi.a
  • /usr/lib/libC.ansi.sl

HP C++ (cfront) Stream Library File Locations (exception handling version)

  • /opt/CC/lib/eh/libC.a
  • /opt/CC/lib/eh/libC.ansi.a


IOStream Library

The shared version of this library is located at /usr/lib/hpux##/libstream.so. The archive version is at /usr/lib/hpux##/libstream.a. (## is 32 or 64 - provided as part of the HP-UX core system).

Manpages: The following manpages are located in the /opt/aCC/share/man/man3.Z directory:

  • IOS.INTRO(3C++) - Introduction to the C++ stream library
  • filebuf(3C++) - Buffer for file input and output
  • fstream(3C++) - iostream and streambuf specialized to files
  • ios(3C++) - input/output formatting
  • istream(3C++) - formatted and unformatted input
  • manip(3C++) - iostream manipulators
  • ostream(3C++) - insertion (storing) into a streambuf
  • sbuf.prot(3C++) - interface for derived classes
  • sbuf.pub(3C++) - public interface of character buffering class
  • ssbuf(3C++) - streambuf specialized to arrays
  • stdiobuf(3C++) - iostream specialized to stdio file
  • strstream(3C++) - iostream specialized to arrays

Header Files: Use the following header files with the IOStream library.

  • iostream.h - I/O streams classes ios, istream, ostream, and streambuf
  • fstream.h
  • strstream.h - streambuf specialized to arrays
  • iomanip.h - predefined manipulators and macros
  • stdiostream.h - specialized streams and streambufs for interaction with stdio
  • stream.h - includes iostream.h, fstream.h, stdiostream.h and iomanip.h for compatibility with AT&T USL C++ v 1.2
To direct the compiler to search these header files, enter the following command:
-I/opt/aCC/include/iostream.

Standard Components Library

The Standard Components Library is provided for compatibility with the cfront based HP C++ compiler. HP recommends that you use the similar features of the Standard C++ Library in place of the Standard Components Library, it is highly recommended that you use the similar features of the Standard C++ Library.

When using the Standard Components Library, note the following:

  • There are command-line differences between HP C++ (cfront) and HP aC++:
    • with cfront use -I /opt/CC/include/SC
    • with HP aC++ use -I /opt/aCC/include/SC
    Note that -l++ is still needed on the link line.
  • The following program development tools that are part of the HP C++ (cfront) compiler are not part of the HP aC++ compiler:
    • — fscpp (symbolic freestore manager)
    • — g2++comp
    • — dem (demangler)
    • — publik
    • — incl
    • — hier

  • compl is a member funtion in the Bit class, which is defined in Bit.h. If you use the Bit class, change your compl calls to compl_.
  • In the HP C++ (cfront) compiler, two sets of Standard Components library files are provided, one for code that uses exception handling and one for code that does not. HP aC++ has just one set of Standard Components library files located at:
    • /opt/aCC/lib/lib++.a
    • /opt/aCC/lib/libGA.a
    • /opt/aCC/lib/libGraph.a

Manpages: The following manpages are located at /opt/aCC/share/man/man3.Z.

  • SC_intro(3C++) - Introduction to Standard Components
  • Args(3C++) - Command-line Arguments
  • Array_alg(3C++) - Operations on Arrays
  • Bits(3C++) - Variable-Length bit Strings
  • Block(3C++) - Parameterized Variable-Size Arrays
  • Fsm(3C++) - Simple Deterministic Finite State Machines
  • Graph(3C++) - Entities and Relationships
  • Graph_alg(3C++) - Operations on Graphs
  • List(3C++) - Parameterized Variable-Length Sequences
  • Map(3C++) - Parameterized Variable-Size Associative Arrays
  • Objection(3C++) - Rudimentary Error-Handling
  • Path(3C++) - Path Names and Search Paths
  • Pool(3C++) - Special-Purpose Memory Allocators
  • Regex(3C++) - Regular Expressions
  • Set(3C++) - Parameterized Unordered Collections
  • Stopwatch(3C++) - Program Execution Time Measurement
  • String(3C++) - Variable-Length Character Strings
  • Strstream(3C++) - Iostream Specialized for String(3C++)
  • Symbol(3C++) - Unique Identifiers Based on Character Strings
  • Time_intro(3C++) and Time(3C++) - Absolute Time, Time Zone and Duration

Header Files: Following is a list of Standard components header files and template source files.
  • Args.h
  • Array_alg.c
  • Array_alg.h
  • bag.c
  • bag.h
  • bagio.c
  • bagio.h
  • Bits.h
  • Block.c
  • Block.h
  • Blockio.c
  • Blockio.h
  • Fsm.h
  • Graph.h
  • Graph_alg.h
  • ipcmonitor.h
  • ipcstream.h
  • ksh_test.h
  • List.c
  • List.h
  • List_old.c
  • List_old.h
  • List_oldio.c
  • List_oldio.h
  • Listio.c
  • Listio.h
  • Map.c
  • Map.h
  • Mapio.c
  • Mapio.h
  • Objection.h
  • Path.h
  • Pool.h
  • Regex.h
  • Search_path.h
  • set.c
  • set.h
  • Set.h
  • set_of_p.c
  • set_of_p.h
  • set_of_pio.c
  • set_of_pio.h
  • setio.c
  • setio.h
  • Stopwatch.h
  • String.h
  • Strstream.h
  • Symbol.h
  • Ticket.h
  • Time.h
  • Tmppath.h

To direct the compiler to search these header files, specify the following command:

-I/opt/aCC/include/SC

Migration Considerations: +inst_implicit_include option for cfront style template definition files

HP C++ 3.x Standard Components Library File Locations

Default version:

  • /usr/lib/lib++.a
  • /usr/lib/libfs.a
  • /usr/lib/libGA.a
  • /usr/lib/libGraph.a
  • /usr/lib/libg2++.a
  • /usr/lib/incl2
  • /usr/lib/hier2
  • /usr/lib/publik2

Exception handling version:

  • /opt/CC/lib/eh/lib++.a
  • /opt/CC/lib/eh/libfs.a
  • /opt/CC/lib/eh/libGA.a
  • /opt/CC/lib/eh/libGraph.a
  • /opt/CC/lib/eh/libg2++.a

HP C++ 10.x Standard Components Library File Locations

Default version:

  • /opt/CC/lib/lib++.a
  • /opt/CC/lib/libfs.a
  • /opt/CC/lib/libGA.a
  • /opt/CC/lib/libGraph.a
  • /opt/CC/lib/libg2++.a
  • /opt/CC/lib/incl2
  • /opt/CC/lib/hier2
  • /opt/CC/lib/publik2

Exception handling version:

  • /opt/CC/lib/eh/lib++.a
  • /opt/CC/lib/eh/libfs.a
  • /opt/CC/lib/eh/libGA.a
  • /opt/CC/lib/eh/libGraph.a
  • /opt/CC/lib/eh/libg2++.a

HP C++ (cfront) Complex Library Not Supported

The Complex library which is part of the cfront based HP C++ compiler product is not included with HP aC++. In place of the Complex library, it is recommended that you use the similar features of the Standard C++ Library.

To begin your migration:

  • Replace #include with <complex>.
  • Remove -lcomplex from the command-line.

Manual Pages Not Available

The following manual pages describing the complex library are not part of the HP aC++ product:

  • CPLX.INTRO(3C++) -- introduction to the C++ complex mathematics library
  • cartpol(3C++) -- cartesian and polar functions
  • cplxexp(3C++) -- exponential, logarithm, power, and square root functions for complex numbers
  • cplxerr(3C++) -- error handling function
  • cplxops(3C++) -- complex number operators
  • cplxtrig(3C++) -- trigonometric and hyperbolic functions for complex numbers

Header File Not Available

The Complex library uses the complex.h header file.
HP C++ (cfront) Task Library Not Supported

The task library which is part of the HP C++ compiler product is not included with HP aC++. To develop multi-threaded applications with HP aC++, use the pthread programming interface routines that are available as part of HP DCE/9000.

Manual Pages Not Available

The following manual pages describing task library features are not part of the HP aC++ product:
  • TASK.INTRO(3C++) -- introduction to the C++ task library
  • interrupt(3C++) -- signal handling
  • queue(3C++) -- queue routines for message passing and data buffering
  • task(3C++) -- the C++ task library
  • tasksim(3C++) -- histograms and random numbers for simulations with C++ tasks

Migration Considerations Related to Preprocessing
For information about HP aC++ performance and file size considerations, refer to the following:
Migration Considerations Related to Preprocessing
The HP C++ (cfront) compiler provides ANSI mode (the default) and K & R compatibility mode preprocessing.

HP aC++ preprocessing complies with the ANSI/ISO C++ International Standard. Therefore, if you are migrating from cfront ANSI mode preprocessing to HP aC++, in general, no changes are required.

HP aC++ does not support K & R compatibility mode preprocessing.

For More Information

Migration Considerations Related to Standardization

The ANSI/ISO C++ International Standard redefines the rules, syntax, and features of C++ language. If your existing code contains any of the standards based keywords as variable names, you must change the variable names when you convert your program to an HP aC++ program.

In addition to keyword changes, there are changes in the following:


C++ Semantics

Following lists the differences in code behavior when you migrate from HP C++ to HP aC++:


Note: These differences can occur inspite of compiling your code without errors.

Implicit Typing of Character String Literals

HP C++ implicitly types character string literals as char *. HP aC++, in accordance with the ANSI/ISO C++ International Standard, types character string literals as const char *. This difference affects function overloading resolution.

Example:
In the following code, HP aC++ calls the first function a; cfront calls the second.


void a(const char *);

void a(char *);



f() {

    a("A_STRING");

    }

To prevent existing code from breaking, assign a string literal to a non-const pointer as shown in the following example:

char *p = "B_STRING";

Also, you cannot convert const char * to char * in a conditional expression in this context.

Example:


char *p = f() ? “A” : “B”;

In such a scenario, you must change the code as in the following example:


const char *p = f() ? “A” : “B”;

or

char *p = const_cast(f() ? “A” : “B”);


Overload Resolution Ambiguity of Subscripting Operator

HP C++ and HP aC++ have different overload resolution models. When you migrate to HP aC++, you may see an overload resolution ambiguity for the subscripting operator. The following code illustrates the problem:


struct String {

   char& operator[](unsigned);

   operator char*();

// ...

};



void f(String &s) {

   s[0] = '0';

}

HP C++ accepts the above code, selecting String::operator[](unsigned) rather than the user-defined conversion, String::operator char*(), followed by the built-in operator[].

Compiling the code with HP aC++ produces the following error:


Error 225: "c.C", line 8 # Ambiguous overloaded function call;

    more than one acceptable function found. Two such functions

    that matched were "char &String::operator [](unsigned int)"

    ["c.C", line 2] and "char &operator [](char *,int)"

    [Built-in operator].

            s[0] = '0';

The error message appears because the compiler cannot choose between:

  1. Not converting s, but converting 0 from type int to type unsigned int; this implies using the user-provided subscript operator[]
  2. Converting s to type char* (using the user-defined conversion operator), but not converting 0; this corresponds to using the built-in subscript operator[].

In order to disambiguate this situation in favor of the user-provided subscript operator[], make the conversion of 0 in alternative (1.) no worse* than the conversion of 0 in alternative (2.).

Because the subscript type for the built-in operator[] is ptrdiff_t (as defined in <stddef.h>), this is also the type that should be used for user-defined subscript operators. Replace the previous example by:


#include <stddef.h>



struct String {

   char& operator[](ptrdiff_t);

   operator char*();

   // ...

};



void f(String &s) {

   s[0] = '0';

}

*worse is relative to a ranking of conversions as described in the ANSI/ISO C++ International Standard on overloading. In general, a user-defined conversion is worse than a standard conversion, which in turn is worse than no conversion at all. The complete rules are more fine grained.


Execution Order of Static Constructors in Shared Libraries

In HP C++ (cfront), static constructors in shared libraries listed on the link-line are executed, by default, in left-to-right order. HP aC++ executes static constructors in depth-first order; that is, shared libraries on which other files depend are initialized first. Use the -depth command-line option on the CC command line for enhanced compatibility with HP aC++.

In addition, HP aC++ reverses the initialization order of .o files on the link-line. To aid in migration, you can group all .o files together and all .so files together.

Example:


aCC file1.o file2.o lib1.so lib2.so lib3.so

In this scenario, cfront would initialize file2.o first, and then file1.o, while HP aC++ initializes file1.o and then file2.o. You must take this into account in your cfront code to avoid link problems with HP aC++.


More Frequent Inlining of Inline Code

HP C++ does not inline some functions even when you request for it. This happens when the function is too complex. If you use the +w option, the compiler displays a message whenever it does not inline a requested function.

HP aC++ almost always inlines functions for which you have specified the inline keyword.


C++ Syntax

When you migrate from HP C++ to HP aC++, in addition to changes related to standards based keywords, you may need to make changes to your source code in the following areas:


Explicit int Declaration

In HP C++, you do not need to explicitly specify int types. In HP aC++, you must explicitly declare int types. This change reduces ambiguity among expressions involving function-like casts and declarations.

Example:

The following code is valid in HP C++:


void f(const parm);

const n = 3;

main()

The equivalent, valid HP aC++ code follows:

void f(const int parm);

const int n = 3;

int main()


for Statement - New Scoping Rules

In HP C++, variables declared in the initializer list are allowed after the for statement. In the ANSI/ISO C++ International Standard, variables declared in the initializer list are not allowed after the for statement. HP aC++ provides this functionality when you specify the following aCC command-line option:


-WC,-ansi_for_scope,on

If you do not specify this option, (or you specify the -WC,-ansi_for_scope,off option), by default, the new rules do not take effect.

In this scenario, HP aC++ provides this standard functionality as an option to ease conversion of existing code to the standard. No code change is currently required. Future plans are to make the ANSI/ISO C++ International Standard syntax the default. HP recommends that you correct your code, by moving the declaration of the for loop variable to its enclosing block.

Example:

The following code currently compiles without errors with HP C++ and HP aC++. In the future, HP aC++, will generate an error.


int main(int argc) {

        for (int i = 1; i < argc; ++i) {

        }

        for (i = 0; i < argc; ++i) {

        }

}

Correct the code as follows:

int main(int argc) {

        int i;

        for (i = 1; i < argc; ++i) {

        }

        for (i = 0; i < argc; ++i) {

        }

}


struct as Template Type Parameter is Permitted

In HP C++, an error is generated when a struct is used as a template type parameter. In HP aC++, when a struct is used as a template type parameter, it is correctly compiled, in accordance with draft standard syntax. This is a new feature.

Example:


template  class A {

public:

struct T a;

};

struct B {};

A b;

The following error is displayed when you compile this code with HP C++:


CC: "DDB4325.C", line 3: error: T of type any redeclared as struct (1479)

This code compiles without error with HP aC++.


Base Template Class Reference Syntax Change

In HP C++, you can reference a member of a base template class without qualifying the member. In HP aC++, when you reference a member of a base template class, you must qualify the member by adding this->.

Adding this-> defers name resolution until instantiation. This allows the compiler to find members in template base classes. However, it prevents the compiler from finding names declared in enclosing scopes.

Example:


template  class BaseT {

public:

  T t;

  int i;

};

template  class DerivedT : public BaseT {

public:

  void foo1 () { t = 1; i = 1; }               //  warning 721

                                               //  t and i could be global.



  void foo2 () { this->t = 2; this->i = 2; }   //  Correct syntax, no warning.

};

DerivedT d;             // Here is the point of instantiation.


Tokens after #endif

In HP C++, any character that follows the #endif preprocessor statement causes a warning and is ignored. In HP aC++, characters following the #endif preprocessor statement cause an error and the program does not compile. To change this, remove all characters following all #endif preprocessor statements or put the token in comments.

Example:

Compiling the following code with HP C++ causes a warning. Compiling with HP aC++ generates an error.


int main(){

   #ifdef FLAG

   int i;

   i=1;

   #endif FLAG

}

To compile with HP aC++, change the code to:

int main(){

   #ifdef FLAG

   int i;

   i=1;

   #endif //FLAG

}


overload not a Keyword

In HP C++, using the overload keyword to specify a function as an overloaded function causes an anachronistic warning and is ignored. In HP aC++, using the overload keyword causes an error and the program does not compile. To change this, remove all occurrences of the overload keyword.

Example:

Compiling the following code with HP C++ causes a warning. Compiling with HP aC++ generates an error stating that overload is used as a type, but has not been defined as a type.


int f(int i);

overload int f(float f); // Remove the word overload.

int main () {

return 1;

}


Dangling Comma in enum

In HP C++, a comma following the last element in an enum list is ignored. In HP aC++, a comma following the last element in an enum list generates an error. To avoid this error, remove the comma after the last element.

Example:


enum Colors { red,

              orange,

              yellow,

              green,

              blue,

              indigo,

              violet,   // This comma is illegal.

};


Static Member Definition Required

In HP C++, you can declare a static member and not define it. However, in HP aC++, you cannot do so. You must define the declared static data member.

Example:

Compiling and linking the following code on HP C++ gives no warning nor error. Compiling the code on HP aC++ gives neither a warning nor an error. Linking the resulting object file generates a linker (ld) error that states that there are unsatisfied symbols.


class A {

public:

   static int staticmember;

};

// int A::staticmember=0;   // This would fix the problem.

int main ()

{

   A::staticmember=1;

}


Declaring friend Classes

In HP C++, you can declare friend classes without the class keyword. In HP aC++, declaring friend classes without the class keyword generates an error. To change this, add the class keyword to all friend class declarations.

Example:

Compiling the following code on HP C++ does not generate a warning or an error. Compiling the code on HP aC++ generates an error stating that the friend declaration for B is not in the right form for either a function or a class.


class foo{



public:

   friend bar;   // Need to say:  friend class B

};

int main (){

   return 1;

}


Incorrect Syntax for Calls to operator new

In HP C++, you can use incorrect syntax to call operator new. In HP aC++, an error is generated when incorrect syntax for operator new is used. To change this, add parentheses around the use of operator new. This code compiles correctly with both HP C++ and HP aC++.

Example:

Compiling the following code on HP C++ does not generate a warning or an error. Compiling the code on HP aC++ generates errors stating operator expected instead of new and undeclared variable operator S.


struct S {

   int f();

};



int g() { 

   return new S->f();

}



// int g() { return (new S)->f();}    // This would fix the problem.



int S:: f( ) { 

      return 1;

}

main() {

   return 1; 

}


Using :: in Class Definitions

In HP C++, you can declare members of classes inside the class using the following incorrect syntax:


class_name::member_name

In HP aC++, this incorrect syntax is considered an error. You must remove the class_name:: specification from the member definition.

Example:

Compiling the following code on HP C++ does not generate a warning or an error. Compiling the code on HP aC++ generates an error stating that you cannot qualify members of class X in the class definition.


class X{

   int X::f();  

// int f();     // This would fix the problem and

                // run successfully on both compilers.

>

int main(){

}


Duplicate Formal Argument Names

In HP C++, duplicate formal argument names are allowed. In HP aC++, duplicate formal argument names generate an error. To avoid this, use unique formal parameter names.

Example:

The following code compiles with HP C++. With HP aC++, an error is generated stating that symbol aParameter has been redefined and where it was previously defined.


int a(int aParameter, int * aParameter);


Ambiguous Function or Object Declaration

In HP C++, an ambiguous function or object declaration compiles without warning, assuming an object declaration. In HP aC++, an ambiguous function or object declaration generates an error. To change this, change the code to remove the ambiguity.

Example:


struct A {A(int);};

struct B {B(const A &); void g();};

void f(int p) {

   B b(A(p));   // Declaration of function or object?

   b.g();       // Error?

}

The ambiguity in the example code is whether b is declared as:

  • A function with one argument (named p) returning an object of type B.
  • An object of type B initialized with a temporary object of type A.

HP C++ compiles this code successfully and assumes b is an object. Compiling the code with HP aC++ generates the following error:


Error: File "objDeclaration.c", Line 5

Left side of '.' requires a class object; type found was a function 'B (A)'.

     Did you try to declare an object with a nested constructor call?

     Such a declaration is interpreted as a function declaration B b(A)

     [File "objDeclaration.c, Line 4].

Modify the code to the following to successfully compile it with both compilers:


struct A {A(int);};

struct B {B(const A &); void g();};



void f(int p) {

   B b = A(p);    // declaration of object

   b.g();         // method call

}


Overloaded Operations ++ and --

You must use the overloaded operations ++ and -- correctly. These operations require a member function with one argument. If the function has no argument, a warning is issued and a postfic is assumed in HP C++.

In HP aC++, the inconsistency between the overloaded function usage and definition is considered an error. To avoid this error, change the class definition so that each overloaded function definition has the correct number of arguments.

Example:


class T {

   public:

      T();

      const T& operator++ ();

};

int main () {

T t;

t++;

}

Compiling the above code with HP C++ generates the following warning:


CC: "pre.C", Line 8: warning: prefix ++/-- used as postfix (anachronism) (935)

Compiling the code with HP aC++ generates the following error:

Error 184: File "pre.C", Line 8

Arithmetic or pointer type expected for operator '++'; type found was 'T'.

To compile the code with HP C++ or HP aC++ use the following class definition:

class T {

   public:

      T();

      const T& operator++ ();     // prefix    old style postfix definition

      const T& operator++ (int);  // postfix

};


Reference Initialization

Illegal reference initialization is no longer allowed. In HP C++, a warning is generated stating that the initializer for a non-constant reference is not an lvalue (anachronism). In HP aC++, an illegal initialization of a reference type generates an error and the program does not compile. To avoid this error, use a constant reference.

Example:


void f() {

   char c = 1;

   int & r = c;

}

Compiling the above code with HP C++ generates the following warning:

C: "nonConstRef.C", line 6: warning: initializer for non-const

reference not an lvalue (anachronism)( (235)

Compiling the code with HP aC++ generates the following error:

Error: File "nonConstRef.C", Line 6

Type mismatch; cannot initialize a 'int &' with a 'char'.

Try changing 'int &' to 'const int &'.

For successful compilation with both compilers, change the code to the following:

void f() {

    char c = 1;

    const int & r = c;

}


Using operator new to Allocate Arrays

In HP C++, operator new is called to allocate memory for an array. In HP aC++, operator new [] is called to allocate memory for an array.

Example:

The following code compiles without error on HP C++.


typedef char CHAR;

typedef unsigned int size_t;

typedef const CHAR *LPCSTR, *PCSTR;

typedef unsigned char BYTE;



void* operator new (size_t nSize, LPCSTR lpszFileName, int nLine);

static char THIS_FILE[] = "mw2.C";

int main() {

   BYTE *p;

   p = new(THIS_FILE, 498) BYTE[50];

}

On HP aC++, the following error is generated:

Error: File "DDB4269.C", Line 10

Expected 1 argument(s) for void *operator new [ ](unsigned int); had 3 instead.


Parentheses in Static Member Initialization List

In HP C++, redundant parentheses are allowed in a static member initialization list. In HP aC++, redundant parentheses in a static member initialization list generate an error and the program does not compile. You must remove the redundant parentheses to compile the program with both compilers.

Example:


class A {

public:

   int i;

   static int (A::*p);

};



int (A::*(A::p)) = &(A::i);

Compiling this code HP aC++ generates the following error:

Error: File "DDB4270.C", Line 7

A pointer to member cannot be created from a parenthesized 

or unqualified name.

To successfully compile the code, remove the parentheses from the last line.

class A {

public:

   int i;

   static int (A::*p);

};



int (A::*(A::p)) = &A::i;


&qualified-id Required in Static Member Initialization List

In HP C++, you can use an unqualified function name in a static member initialization list. In HP aC++, an unqualified function name in a static member initialization list causes an error and the program does not compile. Use the unary operator & followed by a qualified-id in the member initialization list. The resulting code compiles correctly with HP C++ and HP aC++.

Example:


class A {

public:

   int i;

   int j();

static int (A::*p)();

};

int (A::*(A::p))() = j;

Compiling this code with HP aC++ generates the following error:

Error: File "DDB4270A.C", Line 7

Cannot initialize 'int (A::*)()' with 'int (*)()'.

To successfully compile with HP C++ and HP aC++, change the initialization list in line 7 to &A::j;

class A {

public:

   int i;

   int j();

static int (A::*p)();

};

int (A::*(A::p))() = &A::j;


Non-constant Reference Initialization

In HP C++, if you do not initialize a non-constant reference with an lvalue, an anachronistic warning is issued and compilation continues. In HP aC++, an error is issued if you do not use an lvalue for a non-constant reference initialization. Use an lvalue for the reference initialization, or define the reference as a const type.

Example:


void f(int &);

int main () {

   f(3);

   return 0;

}

Compiling this code with HP C++ generates the following warning:

CC: "DDB04313A.C", line 4: warning: temporary used for non-const int & argument;

 no changes will be propagated to actual argument (anachronism) (283)

Compiling the above code with HP aC++ generates the following error:

Future Error: File "DDB04313A.C", Line 4

The initializer for a non-constant reference must be an lvalue.

        Try changing 'int &' to 'const int &'.

To successfully compile the code with either compiler, use one of the two alternatives shown below:

void f(const int &);  // Use a constant reference.

int main () {

   f(3);

   return 0;

}



void f(int &);

int i;

int main () {

   i=3;

   f(i);              // Use an lvalue for reference initialization.

   return 0;

}


Digraph White Space Separators

HP C++ does not support alternative tokens (digraphs). In HP aC++, digraphs are supported and legal C++ syntax can be considered an error because of digraph substitution. Insert a blank between two characters of the digraph.

Example:

C<::A> a;
The characters <: are one of the alternative tokens (digraphs) for which HP aC++ performs a substitution. In this case, <: becomes [. The statement to be compiled becomes C[:A a;, which produces many compilation errors.

To successfully compile this program with either compiler, insert a blank between < and :.


  C< ::A> a;

Migration Considerations when Using Templates

In HP aC++, templates are processed differently than in HP C++ (cfront). HP aC++ does not have a repository. All instantiations are placed in an object (.o) file (with additional information in a .Ia file if you specify the +inst_auto command-line option). You cannot modify these files as was possible with the files in a repository.

See Using HP aC++ Templates for more information.

To begin migrating code containing templates to HP aC++, try to compile and link using the default compile-time instantiation. If this fails with compilation errors, you can compile using one of the following:

  • The +inst_all option to view all compile-time errors, including template instantiation errors. This may generate errors that will not occur in your program, because the draft standard allows template parameters that cannot instantiate all members. The +inst_all option forces instantiation of such members.
  • The +inst_directed option to mask compile-time template instantiation errors.

To reset after all translation units compile successfully:

  1. Remove any .o and .I files. Using a clobber makefile target to remove .I files is similar to removing the ptrepository directory in cfront.
  2. Recompile and link using compile-time instantiation.

Verbose Template Processing Information

Use the +inst v option to replace the cfront -ptv option to process verbose template information.

For More Information


Common Template Migration Syntax Changes

You must use the keyword typname to distinguish types in template code in HP aC++. Also, use the this-> notation to reference data members.


The cfront Implicit Include Convention

The preferred method for specifying template declarations and definitions in HP aC++ is to put declarations and definitions in the same file.

In HP C++ (cfront), for any .h file that contains template declarations, there is a .c file that contains definitions for those templates.

HP aC++ provides the following options to ease migration from HP C++ (cfront):

  • +inst implicit_include: This option instructs the compiler to use the cfront default file, name lookup, for template definition files.
  • +inst include_suffixes: Use this option to replace the cfront -ptS"list" option. This specifies file name extensions for template definition files.


Converting Directed Mode to Explicit Instantiation

If you use directed mode instantiation with the cfront based compiler, an awk script can be used to convert your file to an instantiation file that uses the explicit instantiation syntax:


#!/usr/bin/ksh

# For a Directed-Mode Instantiation file that is the parameter

# to the script, create a file that can be compiled with the

# aC++ compiler using the Explicit Instantiation Syntax.

# (Note that this will only work for classes.)



closure_file=$1

closure_file_base_name=${1%\.*}

eis_file=$closure_file_base_name.eis.C



print "Output file:  $eis_file"

# Get all of the include directives.

grep "#include" $closure_file > /tmp/dmi2eis1.$$



# Collect all of the Directed-Mode Instantiation directives.

grep -v "#include" $closure_file \

  | grep -e ">" -e "<" \

  | grep -v "(" \

  | awk ' {if ($1 != "//") {print $0;} }' >/tmp/dmi2eis2.$$



# Print the line assuming that the last element is the variable

# name followed immediately by a semi-colon.

awk '{ n=split($0,sp0);

   printf("template class");

   for (i=1; i<=(n-1); i++) {

     printf(" %s", sp0[i]);

   }

   printf(";\n");

 }' < /tmp/dmi2eis2.$$ > /tmp/dmi2eis3.$$



    cat /tmp/dmi2eis1.$$ /tmp/dmi2eis3.$$ > $eis_file

    rm -f /tmp/dmi2eis*.$$

Note that explicit instantiation can be used to instantiate a template class and all of its member functions, an individual template function, or a template class's member function.

Note: HP aC++ does not support a C++ to C translator mode. For a list of cfront translator mode options that are obsolete, refer to Translator Mode Options.