C++ User's Guide

Chapter 5 Using Libraries

Libraries provide a way to share code among several applications and a way to reduce the complexity of very large applications. The Sun C++ compiler gives you access to a variety of libraries. This chapter explains how to use these libraries.

The C Libraries

The Solaris operating environment comes with several libraries installed in /usr/lib. Most of these libraries have a C interface. Of these, the libc, libm, and libw libraries are linked by the CC driver by default. The library libthread is linked if you use the -mt option. To link any other system library, use the appropriate -l option at link time. For example, to link the libdemangle library, pass -ldemangle on the CC command line at link time:

demo% CC text.c -ldemangle

The Sun C++ 5.0 compiler has its own runtime support libraries. All C++ applications are linked to these libraries by the CC driver. The C++ compiler also comes with several other useful libraries. See "Libraries Provided With the C++ Compiler" for more information.

Libraries Provided With the C++ Compiler

Several libraries are shipped with the C++ compiler. Some of these libraries are available only in compatibility mode (-compat=4), some are available only in the standard mode (-compat=5), and some in both modes. The libgc and libdemangle libraries have a C interface and can be linked to an application in either mode.

The following table lists the libraries shipped with the C++ compiler and the modes in which they are available.

Library 

Description 

Available Mode (s) 

libCrun

C++ runtime 

-compat=5

libCstd

C++ Standard Library 

-compat=5

libiostream

Classic iostreams 

-compat=5

libC

C++ runtime, classic iostreams 

-compat=4

libC_mtstubs

mtstubs library 

-compat=4, -compat=5

libcomplex

complex library

-compat=4

librwtool

Tools.h++ 7

-compat=4, -compat=5

librwtool_dbg

Debug-enabled Tools.h++ 7

-compat=5

libgc

Garbage collection 

C interface 

libgc_dbg

Debug-enabled garbage collection 

-compat=4, -compat=5

libdemangle

Demangling 

C interface 

C++ Library Descriptions

A brief description of each of these libraries follows.

libCrun: This library contains the runtime support needed by the compiler in the standard mode (-compat=5). It provides support for new/delete, exceptions, and RTTI.

libCstd: This is the C++ Standard Library. In particular, it includes iostreams. If you have existing sources that use the classic iostreams and you want to make use of the standard iostreams, you have to modify your sources to conform to the new interface. See the C++ Standard Library Reference manual for details.

libiostream: This is the classic iostreams library built with -compat=5. If you have existing sources that use the classic iostreams and you want to compile these sources with the standard mode (-compat=5), you can use libiostream without modifying your sources. Use -library=iostream to get this library.

libC: This is the library needed in compatibility mode (-compat=4). It contains the C++ runtime support as well as the classic iostreams.

libC_mtstubs: This library contains stubs of some libthread functions. It gets linked in for single threaded applications. If you build your application with the -mt option, libthread gets linked in place of libC_mtstubs.

libcomplex: This library provides complex arithmetic in compatibility mode (-compat=4). In the standard mode, the complex arithmetic functionality is available in libCstd.

librwtool: (Tools.h++ 7) This is Rogue Wave's Tools.h++ version 7 library.

libgc: This is the garbage collection library (a component of Sun WorkShop Memory Monitor). For further details about this library, point your web browser to the file:

/opt/SUNWspro/SC5.0/htmldocs/locale/C/gc/start.html

If you installed the compiler in a different directory, point your browser to:

install-directory/SC5.0/htmldocs/locale/C/gc/start.html

libdemangle: This library is used for demangling C++ mangled names.

Default C++ Libraries

Some of the C++ libraries are linked by default by the CC driver, while others need to be linked explicitly. In the standard mode, the following libraries are linked by default by the CC driver:-lCstd -lCrun -lC_mtstubs -lm -lw -lcx -lc

In compatibility mode, the following libraries are linked by default:-lC -lC_mtstubs -lm -lw -lcx -lc

See "-library=l[,...l]" for more information.

Related Library Options

The CC driver provides several options to help you use libraries.

A library that is specified with both -library and -staticlib options will be linked statically. Some examples:

demo% CC test.cc -library=rwtools7,iostream

links the Tools.h++ version 7 and libiostream libraries dynamically.

demo% CC test.cc -library=gc -staticlib=gc

links the libgc library statically.

demo% CC test.cc -compat=4 -staticlib=libC

compiles test.cc in compatibility mode and links libC statically. Because libC is linked by default in compatibility mode, you do not have to specify this library with the -library option.

demo% CC test.cc -library=no%Crun,no%Cstd

excludes the libraries libCrun and libCstd, which would otherwise be included by default.

By default, CC links various sets of system libraries depending on the command line options. If you specify -xnolib (or -nolib), CC links only those libraries that are specified explicitly with the -l option on the command line. (When -xnolib or -nolib is used, the -library option is ignored, if present.)

The -R option allows you to build dynamic library search paths into the executable file. At execution time, the runtime linker searches these paths for the shared libraries needed by the application. The CC driver passes -R/opt/SUNWspro/lib to ld by default (if the compiler is installed in the standard location). You can use -norunpath to disable building the default path for shared libraries into the executable.

Using Class Libraries

Generally, two steps are involved in using a class library. First, include the appropriate header in your source code. Second, link your program with the object library.

The iostream Library

The C++ 5.0 compiler provides two implementations of iostreams:

If you have existing C++ sources, your code might look like the following example, which uses classic iostreams.


// file prog1.cc
#include <iostream.h>

int main() {
    cout << "Hello, world!" << endl;
    return 0;
}

The following command compiles in compatibility mode and links prog1.cc into an executable program called prog1. The classic iostream library is part of libC, which is linked by default in compatibility mode.


demo% CC -compat prog1.cc -o prog1

The next example uses standard iostreams.


// file prog1.cc
#include <iostream>

int main() {
    std::cout << "Hello, world!" << std::endl;
    return 0;
}

The following command compiles and links prog2.cc into an executable program called prog2. The program is compiled in standard mode and libCstd, which includes the standard iostream library, is linked by default.


demo% CC prog2.cc -o prog2

The complex Library

The standard library provides a templatized complex library that is similar to the complex library provided with the C++ 4.2 compiler. If you compile in standard mode, you must use <complex> instead of <complex.h>. You cannot use <complex> in compatibility mode.

In compatibility mode, you must explicitly ask for the complex library when linking. In standard mode, the complex library is included in libCstd, and is linked by default.

There is no complex.h header for standard mode. With C++ 4.2, "complex" is the name of a class, but in standard C++, "complex" is the name of a template. It is not possible to provide typedefs that would allow old code to work unchanged. Therefore, code written for 4.2 that uses complex numbers will need some straightforward editing to work with the standard library. For example, the following code was written for 4.2 and will compile in compatibility mode.


// file ex1.cc (compatibility mode)
#include <iostream.h>
#include <complex.h>

int main()
{
    complex x(3,3), y(4,4);
    complex z = x * y;
    cout << "x=" << x << ", y=" << y << ", z=" << z << endl;
}

  

The following example compiles and links ex1.cc in compatibility mode, and then executes the program.


demo% CC -compat ex1.cc -library=complex
demo% a.out
x=(3, 3), y=(4, 4), z=(0, 24)

Here is ex1.cc rewritten as ex2.cc to compile in standard mode:


// file ex2.cc (ex1.cc rewritten for standard mode)
#include <iostream>
#include <complex>
int main()
{
     std::complex<double> x(3,3), y(4,4);
     std::complex<double> z = x * y;
     std::cout << "x=" << x << ", y=" << y << ", z=" << z <<        std::endl;
}

The following example compiles and links the rewritten ex2.cc in standard mode, and then executes the program.


% CC ex2.cc
% a.out
x=(3,3), y=(4,4), z=(0,24)

Linking C++ Libraries

The following table shows the compiler options for linking the C++ libraries. See "-library=l[,...l]" for more information.

Library 

Compile Mode 

Option 

Classic iostream

-compat=4

-compat=5

None needed 

-library=iostream

complex

-compat=4

-compat=5

-library=complex

None needed 

Tools.h++ v7 

-compat=4

-compat=5

-library=rwtool7

-library=rwtool7,iostream

Tools.h++ v7 debug 

-compat=4

-compat=5

-library=rwtool7_dbg

-library=rwtool7_dbg,iostream

Garbage collection 

-compat=4

-compat=5

-library=gc

-library=gc

Garbage collection debug 

-compat=4

-compat=5

-library=gc_dbg

-library=gc_dbg

Statically Linking Standard Libraries

The CC driver links in shared versions of several libraries by default, including libc and libm, by passing a -llib option for each of the default libraries to the linker. (See "Default C++ Libraries" for the list of default libraries for compatibility mode and standard mode.)

If you want any of these default libraries to be linked statically, you can use the -xnolib compiler option. With the -xnolib option, the driver does not pass any -l options to ld; you must pass these options yourself. The following example shows how you would link statically with libCrun, and dynamically with libw, libm, and libc in the Solaris 2.5.1, 2.6, or Solaris 7 environment:


demo% CC test.c -xnolib -lCstd -Bstatic -lCrun \
-Bdynamic -lC_mtstubs -lm -lw -lcx -lc

The order of the -l options is important. The -lCstd, -lCrun, -lm, -lw, and -lcx options appear before -lc.


Note -

The -lcx option does not exist on the x86 platform.


Some CC options link to other libraries. These library links are also suppressed by -xnolib. For example, using the -mt option causes the CC driver to pass -lthread to ld in place of -lC_mtstubs. However, if you use both -mt and -xnolib, the CC driver does not pass -lthread to ld. See "-xnolib" for more information. See Linker and Libraries Guide for more information about ld.

You can also use the -library option along with the -staticlib option to link a C++ library statically. This alternative is much easier than the one described earlier. The previous example, for instance, can be performed as:

demo% CC test.c -staticlib=Crun

Using Shared Libraries

The following shared libraries are included with the C++ compiler:

The occurrence of each shared object linked with the program is recorded in the resulting executable (a.out file); this information is used by ld.so to perform dynamic link editing at runtime. Because the work of incorporating the library code into an address space is deferred, the runtime behavior of the program using a shared library is sensitive to an environment change--that is, moving a library from one directory to another. For example, if your program is linked with libcomplex.so.5 in /opt/SUNWspro/SC5.0/lib in the Solaris 2.6 environment, and the libcomplex.so.5 library is later moved into /opt2/SUNWspro/SC5.0/lib, the following message is displayed when you run the binary code:


ld.so: libcomplex.so.5: not found

You can still run the old binary code without recompiling it by setting the environment variable LD_LIBRARY_PATH to the new library directory.

In a C shell:


demo% setenv LD_LIBRARY_PATH \
/opt2/SUNWspro/SC5.0/lib:${LD_LIBRARY_PATH}

In a Bourne shell:


demo$ LD_LIBRARY_PATH=/opt2/SUNWspro/SC5.0/lib:${LD_LIBRARY_PATH}
demo$ export LD_LIBRARY_PATH

The LD_LIBRARY_PATH has a list of directories, usually separated by colons. When you run a C++ program, the dynamic loader searches the directories in LD_LIBRARY_PATH before the default directories.

Use the ldd command as shown in the following example to see which libraries are linked dynamically in your executable:

% ldd a.out

This step should rarely be necessary, because the shared libraries are seldom moved.


Note -

When shared libraries are opened with dlopen, RTLD_GLOBAL must be used for exceptions to work.


See Linker and Libraries Guide for more information on using shared libraries.

Standard Header Implementation

C has 17 standard headers (<stdio.h>, <string.h>, <stdlib.h>, and others). These headers are delivered as part of Solaris, in the directory /usr/include. C++ has those same headers, with the added requirement that the various declared names appear in both the global namespace and in namespace std. For logistical reasons, the C++ compiler supplies its own versions of these headers instead of replacing those in the /usr/include directory.

C++ also has a second version of each of the C standard headers (<cstdio>, <cstring>, and <cstdlib>) with the various declared names appearing only in namespace std. Finally, C++ adds 32 of its own standard headers (<string>, <utility>, <iostream>).

The obvious implementation of the standard headers would use the name found in C++ source code as the name of a text file to be included. For example, the standard header <string> would refer to a file named string in some directory. That obvious implementation has the following drawbacks:

To solve these problems, the compiler include directory contains a file with the same name as the header, along with a symbolic link to it that has the unique suffix ".SUNWCCh." (SUNW is the prefix for all compiler-related packages, CC is the C++ compiler, and .h is the usual suffix for header files). When you specify <string>, the compiler rewrites it to <string.SUNWCCh> and searches for that name. The suffixed name will be found only in the compiler's own include directory. If the file so found is a symbolic link (which it normally is), the compiler dereferences the link exactly once and uses the result (string in this case) as the file name for error messages and debugger references. The compiler uses the suffixed name when emitting file dependency information.

The name rewriting occurs only for the two forms of the 17 standard C headers and the 32 standard C++ headers, only when they appear in angle brackets and without any path specified. If you use quotes instead of angle brackets, specify any path components, or specify some other header, no rewriting occurs. The following table illustrates common situations.

Source code 

Compiler searches for 

Comments 

<string>

string.SUNWCCh

C++ string templates

<cstring>

cstring.SUNWCCh

A version of C string.h

<string.h>

string.h.SUNWCCh

C string.h

<fcntl.h> 

fcntl.h 

Not a standard C or C++ header 

"string" 

string 

Quotes, not angle bracket 

<../string> 

../string 

Path specified