search    
Hewlett-Packard
Creating and Using Libraries
This section gives an overview of libraries provided with HP aC++ and how you can create and use your own libraries. This section is organized into the following topics: Refer to HP-UX Online Linker and Libraries User’s Guide for more information.

HP aC++ Libraries
In addition to the Standard HP-UX system libraries, HP aC++ provides the following C++ libraries:

C++ Standard Library Change

Technical Corrigenda 1 has changed the STL function make_pair to take their arguments by value instead of const reference. This change brings the HP library into compliance if the enabling macro -D__HP_TC1_MAKE_PAIR is specified at compile time. For binary compatibility reasons, the default behavior is unchanged.


Standard C++ Library

The International Standards Organization (ISO) and the American National Standards Institute (ANSI) have completed the process of standardizing the C++ programming language. A major result of this standardization process is the Standard C++ Library, a large and comprehensive collection of classes and functions.

HP aC++ provides the Rogue Wave implementation of the ANSI/ISO Standard C++ Library. This implementation includes the following features:

  • A subset of data structures and algorithms, updated from the original library developed at Hewlett-Packard by Alex Stepanov and Meng Lee and known as the C++ Standard Template Library (STL). Note that the public domain C++ Standard Template Library is not supported by this Standard C++ Library.
  • A templatized string class.
  • A templatized class for representing complex numbers.
  • A uniform framework for describing the execution environment, through the use of a template class named numeric_limits and specializations for each fundamental data type.
  • Memory management features.
  • Language support features.
  • Exception handling features.

Using the Standard C++ Library

Within a few years the Standard C++ Library will be the standard set of classes and libraries delivered with all ANSI-conforming C++ compilers. Although the design of a large portion of the Standard C++ Library is in many ways not object-oriented, C++ itself excels as a language for manipulating objects. How do you integrate the library’s non-object-oriented architecture with the language’s strengths for manipulating objects?

The key is to use the right tool for each task. Object-oriented design methods and programming techniques are almost without peer as guideposts in the development of large complex software. For the large majority of programming tasks, object-oriented techniques will remain the preferred approach. Products such as Rogue Wave’s Tools.h++ Library which encapsulates the Standard C++ Library with a familiar object-oriented interface, can provide you with the power and the advantages of object-orientation.

Use Standard C++ Library components directly when you need flexibility or highly efficient code. Use the more traditional approaches to object-oriented design, such as encapsulation and inheritance, when you need to model larger problem domains and knit all the pieces into a full solution. When you need to devise an architecture for your application, always consider the use of encapsulation and inheritance to compartmentalize the problem. But if you discover that you need an efficient data structure or algorithm for a compact problem (the kind of problem that often resolves to a single class), look to the Standard C++ Library. The library excels in the creation of reusable classes, where low-level constructs are needed, while traditional OOP techniques really shine when those classes are combined to solve a larger problem.

In the future, most libraries will use the Standard C++ Library as their foundation. By using the Standard C++ Library, either directly or through an encapsulation such as Tools.h++ Library, you help insure interoperability. This is especially important in large projects that may rely on communication between several libraries. A good rule of thumb is to use the highest encapsulation level available to you, but make sure that the Standard C++ Library is available as the base for interlibrary communication and operation.

The C++ language supports a wide range of programming approaches because the problems we need to solve require that range. The language, and now the Standard C++ Library that supports it, are designed to give you the flexibility to approach each unique problem from the best possible angle. The Standard C++ Library, when combined with more traditional OOP techniques, puts a very flexible tool into the hands of anyone building a collection of C++ classes, whether those classes are intended to stand alone as a library or are tailored to a specific task.


How the Standard C++ Library Differs from Other Libraries

A major portion of the Standard C++ Library is comprised of a collection of class definitions for standard data structures and a collection of algorithms commonly used to manipulate such structures. This part of the library was derived from the Standard Template Library or STL. The organization and design of this part of the library differs in almost all respects from the design of most other C++ class libraries, because it avoids encapsulation and uses almost no inheritance.

An emphasis on encapsulation is a key hallmark of object-oriented programming. The emphasis on combining data and functionality into an object is a powerful organization principle in software development; indeed it is the primary organizational technique. Through the proper use of encapsulation, even exceedingly complex software systems can be divided into manageable units and assigned to various members of a team of programmers for development.

Inheritance is a powerful technique for permitting code sharing and software reuse, but it is most applicable when two or more classes share a common set of basic features. For example, in a graphical user interface, two types of windows may inherit from a common base window class, and the individual subclasses will provide any required unique features. In another use of inheritance, object-oriented container classes may ensure common behavior and support code reuse by inheriting from a more general class, and factoring out common member functions.

The designers of the STL decided against using an entirely object-oriented approach, and separated the tasks to be performed using common data structures from the representation of the structures themselves. The STL was designed as a collection of algorithms and, separate from these, a collection of data structures that could be manipulated using the algorithms.


The Non-Object-Oriented Design of the Standard C++ Library

The portion of the Standard C++ Library derived from the STL was purposely designed with an architecture that is not object-oriented. This design has both advantages and disadvantages. Some of them are mentioned below:

  • Smaller Source Code
    There are approximately fifty different algorithms and about a dozen major data structures. This separation has the effect of reducing the size of source code, and decreasing some of the risk that similar activities will have dissimilar interfaces. Were it not for this separation, for example, each of the algorithms would have to be re-implemented in each of the different data structures, requiring several hundred more member functions than are found in the present scheme.

  • Flexibility
    One advantage of the separation of algorithms from data structures is that such algorithms can be used with conventional C++ pointers and arrays. Because C++ arrays are not objects, algorithms encapsulated within a class hierarchy seldom have this ability.

  • Efficiency
    The STL in particular, and the Standard C++ Library in general, provide a low-level approach to developing C++ applications. This low-level approach can be useful when specific programs require an emphasis on efficient coding and speed of execution.

  • Iterators: Mismatches and Invalidations
    The Standard C++ Library data structures use pointer-like objects called iterators to describe the contents of a container. Given the library’s architecture, it is not possible to verify that these iterator elements are matched, that is, that they are derived from the same container. Using (either intentionally or by accident) a beginning iterator from one container with an ending iterator from another is a recipe for certain disaster. It is very important to know that iterators can become invalidated as a result of a subsequent insertion or deletion from the underlying container class. This invalidation is not checked, and use of an invalid iterator can produce unexpected results. Familiarity with the Standard C++ Library will help reduce the number of errors related to iterators.

  • Templates: Errors and Code Bloat
    The flexibility and power of templatized algorithms is, with most compilers, purchased at a loss of precision in diagnostics. Errors in the parameter lists to generic algorithms will sometimes be manifest only as obscure compiler errors for internal functions that are defined many levels deep in template expansions. Again, familiarity with the algorithms and their requirements is a key to successful use of the standard library. Heavy reliance on templates can cause programs to grow larger than expected. You can minimize this problem by learning to recognize the cost of instantiating a particular template class, and by making appropriate design decisions. As compilers become more and more fluent in templates, this will become less of a problem.

  • Multithreading Problems
    The Standard C++ Library must be used carefully in a multithreaded environment. Iterators, because they exist independently of the containers they operate on, cannot be safely passed between threads. Since iterators can be used to modify a non-const container, there is no way to protect such a container if it spawns iterators in multiple threads. Use thread-safe wrappers, such as those provided by Tools.h++ Library, if you need to access a container from multiple threads.


Standard C++ Library Reference

The Standard C++ Library Reference provides an alphabetical listing of all of the classes, algorithms, and function objects in the prior Rogue Wave implementation of the Standard C++ Library.

It is provided as HTML formatted files. You can view these files with an HTML browser by opening the file /opt/aCC/html/libstd/ref.htm.


Incompatibilities Between the Library and the Standard

As the ANSI/ISO C++ International Standard has evolved over time, the Standard C++ Library has not always kept up. Such is the case for the times function object in the functional header file. In the standard, times has been renamed to multiplies. If you want to use multiplies in your code, to be compatible with the ANSI/ISO C++ International Standard, use a conditional compilation flag on the aCC command line.

For example, for the following program, compiles with the command line:

aCC -D__HPACC_USING_MULTIPLIES_IN_FUNCTIONAL test.c

// test.c
int times;                   //user defined variable
#include <functional>
// multiplies can be used in

int main() {}
// end of test.c
Depending on the existence of the conditional compilation flag, functional defines either times, or multiplies, not both.

If you have old source that uses times in header functional and a new source that uses multiplies, the sources cannot be mixed. Mixing the two sources would constitute a non-conforming program, and the old and new sources may or may not link.

If your code uses the old name times, and you want to continue to use the now non-standard times function object, you do not need to do anything to compile the old source.


Tools.h++ Library

The Tools.h++ Library is a foundation class library built on the Standard C++ Library. Use its object oriented capabilities to simplify coding and facilitate code reuseablility.

The Rogue Wave Software Tools.h++ Class Reference describes all of the classes and functions in the Tools.h++ Library. It is intended for use with Rogue Wave Standard C++ Library. It is provided as HTML files. You can view these files with an HTML browser by opening the file /opt/aCC/html/librwtool/ref.htm.


HP aC++ Runtime Support Library

The HP aC++ runtime support library is provided as a shared library, /usr/lib/libCsup.so and as an archive library, /usr/lib/libCsup.a.

The library supports the following functionality:

  • Exception Handling
  • Memory Management (operators new and delete)
  • Start and termination of a C++ program
  • Runtime type identification (type_info)
  • Static object constructors and destructors


IOStream Library

The Standards-based IOstream capabilities of the Standard C++ Library are still evolving. As a result, an HP C++ (cfront) compatible IOStream library is provided in this release.


Linking to C++ Libraries

You can compile and link any C++ modules to one or more libraries. HP aC++ automatically links the following with a C++ executable. Note that when you specify the -b option to create a shared library, these defaults do not apply.

  • /usr/lib/hpux##/libCsup.so (the HP aC++ run-time support library)
  • /usr/lib/hpux##/libstd.so (standard C++ library)
  • /usr/lib/hpux##/libstream.so (iostream library)
  • /usr/lib/hpux##/libc.so (the HP-UX system library)
  • /usr/lib/hpux##/libdl.so (routines for managing shared libraries)
  • /usr/lib/hpux##/libunwind.so (routines for unwinding)
  • /usr/lib/hpux##/libm.so (math library)

(where ## is 32 or 64 - provided as part of the HP-UX core system)


Linking with Shared or Archive Libraries

If you want archive libraries instead of shared libraries, use the -a, archive linker option. To create a completely archived executable, use the +A option. To maintain compatibility on future releases, archive and shared libraries should not be mixed.

Refer to HP-UX Online Linker and Libraries User’s Guide for more information.


Specifying Other Libraries

You can specify other libraries using the -l option. For example, in order to use the Tools.h++ library, specify -lrwtool:

aCC myapp.C -lrwtool
Creating and Using Shared Libraries
This section provides information about shared libraries that is specific to HP aC++. It discusses the following topics:


Compiling for Shared Libraries

To create a C++ shared library, you must first compile your C++ source with either the +z or +Z option. These options create object files containing position-independent code (PIC).

Example:

aCC -c +z util.C
This example compiles util.C, generates position-independent code, and puts the code into the object file util.o. util.o can later be put into a shared library.


Creating a Shared Library

To create a shared library from one or more object files, use the -b option at link time. (The object files must have been compiled with +z or +Z.) The -b option creates a shared library rather than an executable file.

Note: You must use the aCC command to create a C++ shared library. The aCC command ensures that any static constructors and destructors in the shared library are executed at the appropriate times.

Example:

aCC -b -o util.so util.o
This example links util.o and creates the shared library util.so.


Using a Shared Library

To use a shared library, you simply include the name of the library on the aCC command line as you would with an archive library, or use the -l option, as with other libraries.

The linker links the shared library to the executable file it creates. Once you create an executable file that uses a shared library, you must not move the shared library or the dynamic loader (dld.so) will not be able to find it.

Note: You must use the aCC command to link any program that uses a C++ shared library. This is because the aCC command ensures that any static constructors and destructors in the shared library are executed at the appropriate times.

Example:

aCC prog.C util.so
This example compiles prog.C, links it with the shared library util.so, and creates the executable file a.out.


Example of Creating and Using a Shared Library

The following command compiles the two files Strings.C and Arrays.C and creates the two object files Strings.o and Arrays.o. These object files contain position-independent code (PIC):

aCC -c +z Strings.C Arrays.C
The following command builds a shared library named libshape.so from the object files Strings.o and Arrays.o:
 
aCC -b -o libshape.so Strings.o Arrays.o
The following command compiles a program, draw_shapes.C, that uses the shared library, libshape.so:
aCC draw_shapes.C libshape.so


Linking Archive or Shared Libraries

If both an archive version and shared version of a particular library reside in the same directory, the linker links in the shared version by default. You can override this behavior with the -a linker option.

Note: You can use the +A option if you are using only archive libraries to create a completely archived executable.

The -a option tells the linker which type of library to use. The -a option is positional and applies to all subsequent libraries specified with the -l option until the end of the command line or until the next -a option is encountered. Pass the -a option to the linker with the -Wx,args option.

Syntax:
The syntax of the -a linker option when used with aCC is:

-Wl,-a,[archive | shared | shared_archive | archive_shared | default ]
-Wl,-a,archive Select archive libraries. If the archive library does not exist, the linker generates a warning message and does not create the output file.
-Wl,-a,shared Select shared libraries. If the shared library does not exist, the linker generates a warning message and does not create the output file.
-Wl,-a,archive_shared If archive_shared is active, the archive form is preferred, but the shared form is allowed.
-Wl,-a,shared_archive If shared_archive is active, the shared form is preferred but the archive form is allowed.
-Wl,-a,default Select the shared library if it exists; otherwise, select the archive library.

Example:
The following example directs the linker to use the archive version of the library libshape, followed by standard shared libraries if they exist; otherwise select archive versions.

aCC box.o sphere.o -Wl,-a,archive -lshape -Wl,-a,default


Updating a Shared Library

The aCC command cannot replace or delete object modules in a shared library. To update a C++ shared library, you must recreate the library with all the object files you want the library to include.

If, for example, a module in an existing shared library requires a fix, simply recompile the fixed module with the +z or +Z option, then recreate the shared library with the -b option. Programs that use this library will now be using the new versions of the routines. That is, you do not have to relink any programs that use this shared library because they are attached at run time.

Advanced Shared Library Features
This section explains the following additional features available to you with shared libraries:
Forcing the Export of Symbols in main

By default, the linker exports from a program only those symbols that were imported by a shared library. For example, if an executable’s shared libraries do not reference the program’s main routine, the linker does not include the main symbol in the a.out file’s export list.

Normally, this is a problem only when a program explicitly calls shared library management routines.

See Routines and Options to Manage C++ Shared Libraries.

To make the linker export all symbols from a program, use the -Wl,-E option which passes the -E option to the linker.


Binding Times

Because shared library routines and data are not actually contained in the a.out file, the dynamic loader must attach the routines and data to the program at run time. To accelerate program startup time, routines in a shared library are not bound until referenced. (Data items are always bound at program startup.) This deferred binding distributes the overhead of binding across the total execution time of the program and is especially helpful for programs that contain many references that are not likely to be executed.


Forcing Immediate Binding

You can force immediate binding, which forces all routines and data to be bound at startup time. With immediate binding, the overhead of binding occurs only at program startup time, rather than across the program's execution. Immediate binding also detects unresolved symbols at startup time, rather than during program execution. Another use of immediate binding is to provide better interactive performance, if you do not mind program startup taking longer. To force immediate binding, use the option -Wl,-B,immediate.

Example:

The following example forces immediate binding:

aCC -Wl,-B,immediate draw_shapes.o -lshape
To specify default binding, use -Wl,-B,deferred.

Refer to HP-UX Online Linker and Libraries User's Guide for more information.


Side Effects of C++ Shared Libraries

When you use a C++ shared library, all constructors and destructors of non-local static objects in the library are executed. This differs from a C++ archive library where only the constructors and destructors that are actually used in the application are executed.


Routines and Options to Manage C++ Shared Libraries

You can call any of several routines to explicitly load and unload shared libraries, and to obtain information about shared libraries.

If an error occurs when calling shared library management routines, the system error variable, errno, is set to an appropriate error value. Constants are defined for these error values in /usr/include/errno.h. Thus, if a program checks for these values, it must include errno.h:

#include <errno.h>

Refer to errno(2) manpage for more information.


Linker Options to Manage Shared Libraries

Linker options are available for specifying shared library binding time, symbol export, and other shared library management features.

Note: You must use the -W1,args compiler option to specify any linker option on the compiler command line.

Refer HP-UX Online Linker and Libraries User's Guide for more information about library management routines and linker options. Also refer shl_load(3X) and shl_unload(3X) manpages.

Standard HP-UX Libraries and Header Files
Several libraries providing system services are included with HP-UX. You can access HP-UX standard libraries by using header files that declare interfaces to those libraries. These library routines are documented in the HP-UX Reference Manual.

Location of Standard HP-UX Header Files:

The standard HP-UX header files are located in /usr/include.

Using Header Files:

To use a system library function, your HP aC++ source code must include the preprocessor directive #include.

Example:

#include <filename.h>
filename.h is the name of the C++ header file for the library function you want to use. By enclosing filename.h in angle brackets, the HP aC++ compiler looks for that particular header file in a standard location on the system. The compiler first looks for header files in /opt/aCC/include; if none are found, it then searches /usr/include.

You can use header file options to modify the search path.

Example:

If you want to use the getenv function that is in the standard system libraries (/usr/lib/hpux##/lib.so and /usr/lib/libc.a), specify the following:

#include <stdlib.h>
(The external declaration of getenv is found in the header file /usr/include/stdlib.h.)

Migration Considerations when Using Libraries
Refer to Migration Considerations when Using Libraries for more information.