Chapter 17 is actually a list of definitions and descriptions used in the following chapters of the Standard when describing the actual library. Here, we use "Introduction" as an introduction to the GNU implementation of the ISO Standard C++ Library.
The C++ standard specifies the entire set of header files that must be
available to all hosted implementations. Actually, the word
"files" is a misnomer, since the contents of the headers
don't necessarily have to be in any kind of external file. The
only rule is that when one #include
's a header, the
contents of that header become
available, no matter how.
That said, in practice files are used.
There are two main types of include files: header files related to a specific version of the ISO C++ standard (called Standard Headers), and all others (TR1, C++ ABI, and Extensions).
Two dialects of standard headers are supported, corresponding to the 1998 standard as updated for 2003, and the draft of the upcoming 200x standard.
C++98/03 include files. These are available in the default compilation mode, ie -std=c++98
or -std=gnu++98
.
<algorithm> | <iomanip> | <list> | <ostream> | <streambuf> |
<bitset> | <ios> | <locale> | <queue> | <string> |
<complex> | <iosfwd> | <map> | <set> | <typeinfo> |
<deque> | <iostream> | <memory> | <sstream> | <utility> |
<exception> | <istream> | <new> | <stack> | <valarray> |
<fstream> | <iterator> | <numeric> | <stdexcept> | <vector> |
<functional> | <limits> |
<cassert> | <ciso646> | <csetjmp> | <cstdio> | <ctime> |
<cctype> | <climits> | <csignal> | <cstdlib> | <cwchar> |
<cerrno> | <clocale> | <cstdarg> | <cstring> | <cwctype> |
<cfloat> | <cmath> | <cstddef> |
C++0x include files. These are only available in C++0x compilation mode, ie -std=c++0x
or -std=gnu++0x
.
<algorithm> | <iomanip> | <locale> | <regex> | <tuple> |
<array> | <ios> | <map> | <set> | <typeinfo> |
<bitset> | <iosfwd> | <memory> | <sstream> | <type_traits> |
<complex> | <iostream> | <new> | <stack> | <unordered_map> |
<deque> | <istream> | <numeric> | <stdexcept> | <unordered_set> |
<exception> | <iterator> | <ostream> | <streambuf> | <utility> |
<fstream> | <limits> | <queue> | <string> | <valarray> |
<functional> | <list> | <random> | <system_error> | <vector> |
<cassert> | <cfloat> | <cmath> | <cstddef> | <ctgmath> |
<ccomplex> | <cinttypes> | <csetjmp> | <cstdint> | <ctime> |
<cctype> | <ciso646> | <csignal> | <cstdio> | <cuchar> |
<cerrno> | <climits> | <cstdarg> | <cstdlib> | <cwchar> |
<cfenv> | <clocale> | <cstdbool> | <cstring> | <cwctype> |
In addition, TR1 includes as:
<tr1/array> | <tr1/memory> | <tr1/regex> | <tr1/type_traits> | <tr1/unordered_set> |
<tr1/complex> | <tr1/random> | <tr1/tuple> | <tr1/unordered_map> | <tr1/utility> |
<tr1/functional> |
<tr1/cmath> | <tr1/cfloat> | <tr1/cstdarg> | <tr1/cstdio> | <tr1/ctime> |
<tr1/ccomplex> | <tr1/cinttypes> | <tr1/cstdbool> | <tr1/cstdlib> | <tr1/cwchar> |
<tr1/cfenv> | <tr1/climits> | <tr1/cstdint> | <tr1/ctgmath> | <tr1/cwctype> |
Also included are files for the C++ ABI interface:
<cxxabi.h> | <cxxabi_forced.h> |
And a large variety of extensions.
<ext/algorithm> | <ext/debug_allocator.h> | <ext/mt_allocator.h> | <ext/pod_char_traits.h> | <ext/stdio_sync_filebuf.h> |
<ext/array_allocator.h> | <ext/enc_filebuf.h> | <ext/new_allocator.h> | <ext/pool_allocator.h> | <ext/throw_allocator.h> |
<ext/atomicity.h> | <ext/functional> | <ext/numeric> | <ext/rb_tree> | <ext/typelist.h> |
<ext/bitmap_allocator.h> | <ext/iterator> | <ext/numeric_traits.h> | <ext/rope> | <ext/type_traits.h> |
<ext/codecvt_specializations.h> | <ext/malloc_allocator.h> | <ext/pb_ds/assoc_container.h> | <ext/slist> | <ext/vstring.h> |
<ext/concurrence.h> | <ext/memory> | <ext/pb_ds/priority_queue.h> | <ext/stdio_filebuf.h> |
<debug/bitset> | <debug/list> | <debug/set> | <debug/unordered_map> | <debug/vector> |
<debug/deque> | <debug/map> | <debug/string> | <debug/unordered_set> |
<parallel/algorithm> | <parallel/numeric> |
A few simple rules.
First, mixing different dialects of the standard headers is not possible. It's an all-or-nothing affair. Thus, code like
#include <array> #include <functional>
Implies C++0x mode. To use the entities in <array>, the C++0x compilation mode must be used, which implies the C++0x functionality (and deprecations) in <functional> will be present.
Second, the other headers can be included with either dialect of
the standard headers, although features and types specific to C++0x
are still only enabled when in C++0x compilation mode. So, to use
rvalue references with __gnu_cxx::vstring
, or to use the
debug-mode versions of std::unordered_map
, one must use
the std=gnu++0x
compiler flag. (Or std=c++0x
, of course.)
A special case of the second rule is the mixing of TR1 and C++0x facilities. It is possible (although not especially prudent) to include both the TR1 version and the C++0x version of header in the same translation unit:
#include <tr1/type_traits> #include <type_traits>
Several parts of C++0x diverge quite substantially from TR1 predecessors.
namespace std
The standard specifies that if one includes the C-style header
(<math.h> in this case), the symbols will be available
in the global namespace and perhaps in
namespace std::
(but this is no longer a firm
requirement.) One the other hand, including the C++-style
header (<cmath>) guarantees that the entities will be
found in namespace std and perhaps in the global namespace.
Usage of C++-style headers is recommended, as then
C-linkage names can be disambiguated by explicit qualification, such
as by std::abort
. In addition, the C++-style headers can
use function overloading to provide a simpler interface to certain
families of C-functions. For instance in <cmath>, the
function std::sin
has overloads for all the builtin
floating-point types. This means that std::sin
can be
used uniformly, instead of a combination
of std::sinf
, std::sin
,
and std::sinl
.
There are three base header files that are provided. They can be used to precompile the standard headers and extensions into binary files that may the be used to speed compiles that use these headers.
Includes all standard headers. Actual content varies depending on language dialect.
Includes all of <stdc++.h>, and adds all the TR1 headers.
Includes all of <stdtr1c++.h>, and adds all the Extension headers.
How to construct a .gch file from one of these base header files.
First, find the include directory for the compiler. One way to do this is:
g++ -v hello.cc #include <...> search starts here: /mnt/share/bld/H-x86-gcc.20071201/include/c++/4.3.0 ... End of search list.
Then, create a precompiled header file with the same flags that will be used to compile other projects.
g++ -Winvalid-pch -x c++-header -g -O2 -o ./stdc++.h.gch /mnt/share/bld/H-x86-gcc.20071201/include/c++/4.3.0/x86_64-unknown-linux-gnu/bits/stdc++.h
The resulting file will be quite large: the current size is around thirty megabytes.
How to use the resulting file.
g++ -I. -include stdc++.h -H -g -O2 hello.cc
Verification that the PCH file is being used is easy:
g++ -Winvalid-pch -I. -include stdc++.h -H -g -O2 hello.cc -o test.exe ! ./stdc++.h.gch . /mnt/share/bld/H-x86-gcc.20071201/include/c++/4.3.0/iostream . /mnt/share/bld/H-x86-gcc.20071201include/c++/4.3.0/string
The exclamation point to the left of the stdc++.h.gch
listing means that the generated PCH file was used, and thus the
Detailed information about creating precompiled header files can be found in the GCC documentation.
There are three main namespaces.
The ISO C++ standards specify that "all library entities are defined
within namespace std." This includes namepaces nested
within namespace std
, such as namespace
std::tr1
.
Specified by the C++ ABI. This ABI specifies a number of type and function APIs supplemental to those required by the ISO C++ Standard, but necessary for interoperability.
Indicating one of several GNU extensions. Choices
include __gnu_cxx
, __gnu_debug
, __gnu_parallel
,
and __gnu_pbds
.
A complete list of implementation namespaces (including namespace contents) is available in the generated source documentation.
std::
One standard requirement is that the library components are defined
in namespace std::
. Thus, in order to use these types or
functions, one must do one of two things:
put a kind of
using-declaration in your source
(either using namespace std;
or i.e. using
std::string;
) This approach works well for individual source files, but
should not be used in a global context, like header files.
use a fully
qualified name for each library symbol
(i.e. std::string
, std::cout
) Always can be
used, and usually enhanced, by strategic use of typedefs. (In the
cases where the qualified verbiage becomes unwieldy.)
Best practice in programming suggests sequestering new data or functionality in a sanely-named, unique namespace whenever possible. This is considered an advantage over dumping everything in the global namespace, as then name look-up can be explicitly enabled or disabled as above, symbols are consistently mangled without repetitive naming prefixes or macros, etc.
For instance, consider a project that defines most of its classes in namespace gtk
. It is possible to
adapt namespace gtk
to namespace std
by using a C++-feature called
namespace composition. This is what happens if
a using-declaration is put into a
namespace-definition: the imported symbol(s) gets imported into the
currently active namespace(s). For example:
namespace gtk { using std::string; using std::tr1::array; class Window { ... }; }
In this example, std::string
gets imported into
namespace gtk
. The result is that use of
std::string
inside namespace gtk can just use string
, without the explicit qualification.
As an added bonus,
std::string
does not get imported into
the global namespace. Additionally, a more elaborate arrangement can be made for backwards compatibility and portability, whereby the
using
-declarations can wrapped in macros that
are set based on autoconf-tests to either "" or i.e. using
std::string;
(depending on whether the system has
libstdc++ in std::
or not). (ideas from
<llewelly@dbritsch.dsl.xmission.com>, Karl Nelson
<kenelson@ece.ucdavis.edu>)
All pre-processor switches and configurations are all gathered
in the file c++config.h
, which is generated during
the libstdc++ configuration and build process, and included by
files part of the public libstdc++ API. Most of these macros
should not be used by consumers of libstdc++, and are reserved
for internal implementation use. These macros cannot be
redefined. However, a select handful of these macro
control libstdc++ extensions and extra features, or provide
versioning information for the API, and are able to be used.
All library macros begin with _GLIBCXX_
(except for
versions 3.1.x to 3.3.x, which use _GLIBCPP_
).
Below is the macro which users may check for library version information.
__GLIBCXX__
Below are the macros which users may change with #define/#undef or with -D/-U compiler flags. The default state of the symbol is listed.
"Configurable" (or "Not configurable") means that the symbol is initially chosen (or not) based on --enable/--disable options at library build and configure time (documented here), with the various --enable/--disable choices being translated to #define/#undef).
"ABI" means that changing from the default value may mean changing the ABI of compiled code. In other words, these choices control code which has already been compiled (i.e., in a binary such as libstdc++.a/.so). If you explicitly #define or #undef these macros, the headers may see different code paths, but the libraries which you link against will not. Experimenting with different values with the expectation of consistent linkage requires changing the config headers before building/installing the library.
_GLIBCXX_DEPRECATED
-std=c++98
and -std=c++0x
. This may
be useful in updating old C++ code which no longer meet the
requirements of the language, or for checking current code
against new language standards. _GLIBCXX_FORCE_NEW
--enable-libstdcxx-allocator
. ABI-changing.
_GLIBCXX_CONCEPT_CHECKS
--enable-concept-checks
.
When defined, performs compile-time checking on certain template
instantiations to detect violations of the requirements of the
standard. This is described in more detail here._GLIBCXX_DEBUG
_GLIBCXX_DEBUG_PEDANTIC
_GLIBCXX_PARALLEL
This section discusses issues surrounding the proper compilation of multithreaded applications which use the Standard C++ library. This information is GCC-specific since the C++ standard does not address matters of multithreaded applications. Unless explicitly prefaced, all information in this section is relevant to the GCC 3.0 release and all later releases.
Earlier GCC releases had a somewhat different approach to threading configuration and proper compilation. Before GCC 3.0, configuration of the threading model was dictated by compiler command-line options and macros (both of which were somewhat thread-implementation and port-specific). There were no guarantees related to being able to link code compiled with one set of options and macro setting with another set. For GCC 3.0, configuration of the threading model used with libraries and user-code is performed when GCC is configured and built using the --enable-threads and --disable-threads options. The ABI is stable for symbol name-mangling and limited functional compatibility exists between code compiled under different threading models.
All normal disclaimers aside, multithreaded C++ application are
only supported when libstdc++ and all user code was built with
compilers which report (via gcc/g++ -v
) the same thread
model and that model is not single. As long as your
final application is actually single-threaded, then it should be
safe to mix user code built with a thread model of
single with a libstdc++ and other C++ libraries built
with another thread model useful on the platform. Other mixes
may or may not work but are not considered supported. (Thus, if
you distribute a shared C++ library in binary form only, it may
be best to compile it with a GCC configured with
--enable-threads for maximal interchangeability and usefulness
with a user population that may have built GCC with either
--enable-threads or --disable-threads.)
When you link a multithreaded application, you will probably need to add a library or flag to g++. This is a very non-standardized area of GCC across ports. Some ports support a special flag (the spelling isn't even standardized yet) to add all required macros to a compilation (if any such flags are required then you must provide the flag for all compilations not just linking) and link-library additions and/or replacements at link time. The documentation is weak. Here is a quick summary to display how ad hoc this is: On Solaris, both -pthreads and -threads (with subtly different meanings) are honored. On OSF, -pthread and -threads (with subtly different meanings) are honored. On Linux/i386, -pthread is honored. On FreeBSD, -pthread is honored. Some other ports use other switches. AFAIK, none of this is properly documented anywhere other than in ``gcc -dumpspecs'' (look at lib and cpp entries).
See FAQ (general overview), 23 (containers), and 27 (I/O) for more information.
The libstdc++ library has been designed so that it can be used in multithreaded applications (with libstdc++-v2 this was only true of the STL parts.) The first problem is finding a fast method of implementation portable to all platforms. Due to historical reasons, some of the library is written against per-CPU-architecture spinlocks and other parts against the gthr.h abstraction layer which is provided by gcc. A minor problem that pops up every so often is different interpretations of what "thread-safe" means for a library (not a general program). We currently use the same definition that SGI uses for their STL subset. However, the exception for read-only containers only applies to the STL components. This definition is widely-used and something similar will be used in the next version of the C++ standard library.
Here is a small link farm to threads (no pun) in the mail archives that discuss the threading problem. Each link is to the first relevant message in the thread; from there you can use "Thread Next" to move down the thread. This farm is in latest-to-oldest order.
(A large selection of links to older messages has been removed; many of the messages from 1999 were lost in a disk crash, and the few people with access to the backup tapes have been too swamped with work to restore them. Many of the points have been superseded anyhow.)
This section will be updated as new and interesting issues come to light.
Return to top of page or to the FAQ.
The ISO standard defines the following phrase:
[1.3.5] implementation-defined behavior
- behavior, for a well-formed program construct and correct data, that depends on the implementation and that each implementation shall document.
We do so here, for the C++ library only. Behavior of the compiler, linker, runtime loader, and other elements of "the implementation" are documented elsewhere. Everything listed in Annex B, Implementation Qualities, are also part of the compiler, not the library.
For each entry, we give the section number of the standard, when applicable. This list is probably incomplet and inkorrekt.
[1.9]/11 #3 If isatty(3)
is true, then
interactive stream support is implied.
[17.4.4.5] Non-reentrant functions are probably best discussed in the various sections on multithreading (see above).
[18.1]/4 The type of NULL
is described
here.
[18.3]/8 Even though it's listed in the library sections, libstdc++ has zero control over what the cleanup code hands back to the runtime loader. Talk to the compiler people. :-)
[18.4.2.1]/5 (bad_alloc),
[18.5.2]/5 (bad_cast),
[18.5.3]/5 (bad_typeid),
[18.6.1]/8 (exception),
[18.6.2.1]/5 (bad_exception): The what()
member function of class std::exception
, and these other
classes publicly derived from it, simply returns the name of the
class. But they are the mangled names; you will need to call
c++filt
and pass the names as command-line parameters to
demangle them, or call a
runtime demangler function.
(The classes in <stdexcept>
have constructors which
require an argument to use later for what()
calls, so the
problem of what()
's value does not arise in most
user-defined exceptions.)
[18.5.1]/7 The return value of
std::type_info::name()
is the mangled type name (see the
previous entry for more).
[20.1.5]/5 "Implementors are encouraged to supply libraries that can accept allocators that encapsulate more general memory models and that support non-equal instances. In such implementations, any requirements imposed on allocators by containers beyond those requirements that appear in Table 32, and the semantics of containers and algorithms when allocator instances compare non-equal, are implementation-defined." As yet we don't have any allocators which compare non-equal, so we can't describe how they behave.
[21.1.3.1]/3,4,
[21.1.3.2]/2,
[23.*]'s foo::iterator,
[27.*]'s foo::*_type,
others...
Nope, these types are called implementation-defined because you
shouldn't be taking advantage of their underlying types. Listing them
here would defeat the purpose. :-)
[21.1.3.1]/5 I don't really know about the mbstate_t stuff... see the chapter 22 notes for what does exist.
[22.*] Anything and everything we have on locale implementation will be described over here.
[26.2.8]/9 I have no idea what
complex<T>
's pow(0,0) returns.
[27.4.2.4]/2 Calling
std::ios_base::sync_with_stdio
after I/O has already been
performed on the standard stream objects will
flush the buffers, and
destroy and recreate the underlying buffer instances. Whether or not
the previously-written I/O is destroyed in this process depends mostly
on the --enable-libio choice: for stdio, if the written data is
already in the stdio buffer, the data may be completely safe!
[27.6.1.1.2],
[27.6.2.3] The I/O sentry ctor and dtor can perform
additional work than the minimum required. We are not currently taking
advantage of this yet.
[27.7.1.3]/16,
[27.8.1.4]/10
The effects of pubsetbuf/setbuf
are described
in this chapter.
[27.8.1.4]/16 Calling fstream::sync
when
a get area exists will... whatever fflush()
does, I think.
Return to top of page or to the FAQ.
Return to top of page or to the FAQ.
See license.html for copying conditions. Comments and suggestions are welcome, and may be sent to the libstdc++ mailing list.