Creating and Using Libraries

Choose from the following topics for information about the libraries provided with HP aC++ as well as how you can create and use your own libraries.

For additional background, refer to the HP-UX Online Linker and Libraries User's Guide which is frequently referenced in these sections.

Migration

See Also


HP aC++ Libraries

In addition to standard HP-UX system libraries, HP aC++ provides the following C++ libraries.

Standards Based Libraries

HP C++ (cfront) Compatibility Libraries

NOTE: HP aC++ provides the following libraries whose functionality is also provided with HP C++ (cfront). These libraries are not standards based.

See Also:


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. Choose from the following for more details.

Introductory Concepts

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

For More Information

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. Be aware that 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.

Introduction to 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.

Standard C++ Library Reference

Select from the following categories to see further explanation from the Rogue Wave Software Standard C++ Library 1.2.1 Class Reference. Corresonding header file(s) are noted at the beginning of each category. Note that system man pages are also available.

NOTE: If you are accessing this guide from the World Wide Web URL, http://docs.hp.com, rather than from a system on which HP aC++ is installed, Rogue Wave documentation is not available. The following links will not succeed.

Algorithms

Generic Algorithms-- for performing various operations on containers and sequences: #include <algorithm>

Allocators

The Standard C++ Library allocator interface encapsulates the types and functions needed to manage the storage of data in a generic way. The interface wraps the mechanism for managing data storage and separates this mechanism from the classes and functions used to maintain associations between data elements. This eliminates the need to rewrite containers and algorithms to suit different storage mechanisms. You can encapsulate all the storage mechanism details in an allocator, then provide that allocator to an existing container when appropriate.

The Standard C++ Library provides a default allocator class that implements this interface using the standard new and delete operators for all storage management.

Complex Number Library

Operations used to create and manipulate complex numbers. #include <complex>

Containers

Collection classes are often described as Containers. A container stores a collection of other objects and provides certain basic functionality that supports the use of generic algorithms. Containers come in two basic flavors: sequences and associative_containers. They are further distinguished by the type of iterator they support.

#include <bitset> #include <deque> #include <ul> #include <map> for map and multimap #include <queue> for queue and priority_queue #include <set> for set and multiset #include <stack> #include <vector>

Exception Class

#include <exception>

Function Adaptors

Used to build new function objects out of existing function objects. #include <functional>

Function Objects

Objects with an operator() defined. Function objects are used in place of pointers to functions as arguments to templated algorithms.

#include <functional>

Generalized Numeric Operations

#include <numeric>

Insert Iterators

Insert Iterators are adaptors that allow an iterator to insert into a container rather than overwrite elements in the container.

#include <iterator>

Iterator Operations

#include <iterator>

Iterators

Iterators are pointer generalizations for traversal and modification of collections.

#include <iterator>

Memory Handling Primitives

#include <memory>

Memory Management

#include <memory>

Numeric Limits Library

#include <limits>

Stream Iterators

#include <iterator> Stream iterators allow generic algorithms to be used directly on streams.

String Library

#include <string>

Utility Classes

#include <utility>

Utility Operators

#include <utility>


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. Choose from the following for more information:


HP aC++ Run-time Support Library

The HP aC++ run-time support library is provided as a shared library, /usr/lib/libCsup.sl and as an archive library, /usr/lib/libCsup.a.

The library supports the following functionality:

For More Information


IOStream Library

NOTE: At this release of HP aC++, 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.

For More Information


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.

For ## substitute either 32 or 64 as appropriate.

Linking with Shared or Archive Libraries

If you want archive libraries instead of shared libraries, use the -a,archive linker option.

NOTE: To maintain compatibility on future releases, archive and shared libraries should not be mixed. Refer to the "Mixing Shared and Archive Libraries" section in the HP-UX Online Linker and Libraries User's Guide.

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++.

Select one of the following topics:

For More Information

Compiling for Shared Libraries

By default, aC++ generates position independent code (PIC), so no specific action is required. For more information on Symbol Binding, see -B

Creating a Shared Library

To create a shared library from one or more object files, use the -b option at link time. The -b option creates a shared library rather than an executable file.

CAUTION: You must use the aCC command to create 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 -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(5)) will not be able to find it.

CAUTION: 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.

aCC -c  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 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.

The -a linker 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
        default}

The different meanings of this option are:

-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,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 then recreate the shared library with the -b option. Any 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 additional things you can do with shared libraries. For more information about Symbol Binding, see -B

Select one of the following:

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 don't 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.

For More Information

For more information, see the HP-UX Online Linker and Libraries User's Guide. Also see dlopen(3) and dlclose(3).

Side Effects of C++ Shared Libraries

When you use a C++ shared library, all constructors and destructors of nonlocal 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 (see errno(2)). Thus, if a program checks for these values, it must include errno.h:

#include <errno.h>

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 -Wx,args compiler option to specify any linker option on the compiler command line.

For More Information

Version Control for Shared Libraries

For More Information

For more information about version control in shared libraries, refer to the HP-UX Online Linker and Libraries User's Guide.

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. For example,

#include <filename.h>

where 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 of Using a Standard Header File

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

#include <stdlib.h>

because the external declaration of getenv is found in the header file /usr/include/stdlib.h.


HP aC++ File Locations

HP aC++ Executable Files

HP aC++ Run-time Libraries and Header Files

Note that some of the following run-time libraries are provided in both shared and archive versions.

Header files for these libraries are located at /opt/aCC/include*.

For ## substitute 32 or 64 as appropriate.