*: Remove all but contents of ext/pb_ds.
2008-02-11 Benjamin Kosnik <bkoz@redhat.com> * doc/html/*: Remove all but contents of ext/pb_ds. * doc/html/index.html: New. * doc/html/README: New. From-SVN: r132250
This commit is contained in:
parent
c9024a78a9
commit
620039adfb
59 changed files with 52 additions and 31393 deletions
|
@ -1,3 +1,9 @@
|
|||
2008-02-11 Benjamin Kosnik <bkoz@redhat.com>
|
||||
|
||||
* doc/html/*: Remove all but contents of ext/pb_ds.
|
||||
* doc/html/index.html: New.
|
||||
* doc/html/README: New.
|
||||
|
||||
2008-02-11 Benjamin Kosnik <bkoz@redhat.com>
|
||||
|
||||
* doc/doxygen/mainpage.html: Add in corrected links.
|
||||
|
|
|
@ -1,182 +0,0 @@
|
|||
|
||||
This is the list of names "reserved to the implementation" that
|
||||
have been claimed by certain compilers and system headers of interest,
|
||||
and should not be used in the library. It will grow, of course.
|
||||
We generally are interested in names that are not all-caps, except
|
||||
for those like "_T"
|
||||
|
||||
For Solarix:
|
||||
_B
|
||||
_C
|
||||
_L
|
||||
_N
|
||||
_P
|
||||
_S
|
||||
_U
|
||||
_X
|
||||
_E1
|
||||
..
|
||||
_E24
|
||||
|
||||
Irix adds:
|
||||
_A
|
||||
_G
|
||||
|
||||
MS adds:
|
||||
_T
|
||||
|
||||
BSD adds:
|
||||
__used
|
||||
__unused
|
||||
__inline
|
||||
_Complex
|
||||
__istype
|
||||
__maskrune
|
||||
__tolower
|
||||
__toupper
|
||||
__wchar_t
|
||||
__wint_t
|
||||
_res
|
||||
_res_ext
|
||||
__tg_*
|
||||
|
||||
For GCC:
|
||||
|
||||
[Note that this list is out of date. It applies to the old
|
||||
name-mangling; in G++ 3.0 and higher a different name-mangling is
|
||||
used. In addition, many of the bugs relating to G++ interpreting
|
||||
these names as operators have been fixed.]
|
||||
|
||||
The full set of __* identifiers (combined from gcc/cp/lex.c and
|
||||
gcc/cplus-dem.c) that are either old or new, but are definitely
|
||||
recognized by the demangler, is:
|
||||
|
||||
__aa
|
||||
__aad
|
||||
__ad
|
||||
__addr
|
||||
__adv
|
||||
__aer
|
||||
__als
|
||||
__alshift
|
||||
__amd
|
||||
__ami
|
||||
__aml
|
||||
__amu
|
||||
__aor
|
||||
__apl
|
||||
__array
|
||||
__ars
|
||||
__arshift
|
||||
__as
|
||||
__bit_and
|
||||
__bit_ior
|
||||
__bit_not
|
||||
__bit_xor
|
||||
__call
|
||||
__cl
|
||||
__cm
|
||||
__cn
|
||||
__co
|
||||
__component
|
||||
__compound
|
||||
__cond
|
||||
__convert
|
||||
__delete
|
||||
__dl
|
||||
__dv
|
||||
__eq
|
||||
__er
|
||||
__ge
|
||||
__gt
|
||||
__indirect
|
||||
__le
|
||||
__ls
|
||||
__lt
|
||||
__max
|
||||
__md
|
||||
__method_call
|
||||
__mi
|
||||
__min
|
||||
__minus
|
||||
__ml
|
||||
__mm
|
||||
__mn
|
||||
__mult
|
||||
__mx
|
||||
__ne
|
||||
__negate
|
||||
__new
|
||||
__nop
|
||||
__nt
|
||||
__nw
|
||||
__oo
|
||||
__op
|
||||
__or
|
||||
__pl
|
||||
__plus
|
||||
__postdecrement
|
||||
__postincrement
|
||||
__pp
|
||||
__pt
|
||||
__rf
|
||||
__rm
|
||||
__rs
|
||||
__sz
|
||||
__trunc_div
|
||||
__trunc_mod
|
||||
__truth_andif
|
||||
__truth_not
|
||||
__truth_orif
|
||||
__vc
|
||||
__vd
|
||||
__vn
|
||||
|
||||
SGI badnames:
|
||||
__builtin_alloca
|
||||
__builtin_fsqrt
|
||||
__builtin_sqrt
|
||||
__builtin_fabs
|
||||
__builtin_dabs
|
||||
__builtin_cast_f2i
|
||||
__builtin_cast_i2f
|
||||
__builtin_cast_d2ll
|
||||
__builtin_cast_ll2d
|
||||
__builtin_copy_dhi2i
|
||||
__builtin_copy_i2dhi
|
||||
__builtin_copy_dlo2i
|
||||
__builtin_copy_i2dlo
|
||||
__add_and_fetch
|
||||
__sub_and_fetch
|
||||
__or_and_fetch
|
||||
__xor_and_fetch
|
||||
__and_and_fetch
|
||||
__nand_and_fetch
|
||||
__mpy_and_fetch
|
||||
__min_and_fetch
|
||||
__max_and_fetch
|
||||
__fetch_and_add
|
||||
__fetch_and_sub
|
||||
__fetch_and_or
|
||||
__fetch_and_xor
|
||||
__fetch_and_and
|
||||
__fetch_and_nand
|
||||
__fetch_and_mpy
|
||||
__fetch_and_min
|
||||
__fetch_and_max
|
||||
__lock_test_and_set
|
||||
__lock_release
|
||||
__lock_acquire
|
||||
__compare_and_swap
|
||||
__synchronize
|
||||
__high_multiply
|
||||
__unix
|
||||
__sgi
|
||||
__linux__
|
||||
__i386__
|
||||
__i486__
|
||||
__cplusplus
|
||||
__embedded_cplusplus
|
||||
// long double conversion members mangled as __opr
|
||||
// http://gcc.gnu.org/ml/libstdc++/1999-q4/msg00060.html
|
||||
_opr
|
|
@ -1,399 +0,0 @@
|
|||
|
||||
C++ Standard Library Coding Style Guidelines
|
||||
-------------------------------------
|
||||
|
||||
This library is written to appropriate C++ coding standards. As such,
|
||||
it is intended to precede the recommendations of the GNU Coding
|
||||
Standard, which can be referenced in full here:
|
||||
|
||||
http://www.gnu.org/prep/standards/standards.html#Formatting
|
||||
|
||||
The rest of this is also interesting reading, but skip the "Design
|
||||
Advice" part.
|
||||
|
||||
The GCC coding conventions are here, and are also useful:
|
||||
http://gcc.gnu.org/codingconventions.html
|
||||
|
||||
In addition, because it doesn't seem to be stated explicitly anywhere
|
||||
else, there is an 80 column source limit.
|
||||
|
||||
ChangeLog entries for member functions should use the
|
||||
classname::member function name syntax as follows:
|
||||
|
||||
1999-04-15 Dennis Ritchie <dr@att.com>
|
||||
|
||||
* src/basic_file.cc (__basic_file::open): Fix thinko in
|
||||
_G_HAVE_IO_FILE_OPEN bits.
|
||||
|
||||
Notable areas of divergence from what may be previous local practice
|
||||
(particularly for GNU C) include:
|
||||
|
||||
01. Pointers and references
|
||||
char* p = "flop";
|
||||
char& c = *p;
|
||||
-NOT-
|
||||
char *p = "flop"; // wrong
|
||||
char &c = *p; // wrong
|
||||
|
||||
Reason: In C++, definitions are mixed with executable code. Here,
|
||||
p is being initialized, not *p. This is near-universal
|
||||
practice among C++ programmers; it is normal for C hackers
|
||||
to switch spontaneously as they gain experience.
|
||||
|
||||
02. Operator names and parentheses
|
||||
operator==(type)
|
||||
-NOT-
|
||||
operator == (type) // wrong
|
||||
|
||||
Reason: The == is part of the function name. Separating
|
||||
it makes the declaration look like an expression.
|
||||
|
||||
03. Function names and parentheses
|
||||
void mangle()
|
||||
-NOT-
|
||||
void mangle () // wrong
|
||||
|
||||
Reason: no space before parentheses (except after a control-flow
|
||||
keyword) is near-universal practice for C++. It identifies the
|
||||
parentheses as the function-call operator or declarator, as
|
||||
opposed to an expression or other overloaded use of parentheses.
|
||||
|
||||
04. Template function indentation
|
||||
template<typename T>
|
||||
void
|
||||
template_function(args)
|
||||
{ }
|
||||
-NOT-
|
||||
template<class T>
|
||||
void template_function(args) {};
|
||||
|
||||
Reason: In class definitions, without indentation whitespace is
|
||||
needed both above and below the declaration to distinguish
|
||||
it visually from other members. (Also, re: "typename"
|
||||
rather than "class".) T often could be int, which is
|
||||
not a class. ("class", here, is an anachronism.)
|
||||
|
||||
05. Template class indentation
|
||||
template<typename _CharT, typename _Traits>
|
||||
class basic_ios : public ios_base
|
||||
{
|
||||
public:
|
||||
// Types:
|
||||
};
|
||||
-NOT-
|
||||
template<class _CharT, class _Traits>
|
||||
class basic_ios : public ios_base
|
||||
{
|
||||
public:
|
||||
// Types:
|
||||
};
|
||||
-NOT-
|
||||
template<class _CharT, class _Traits>
|
||||
class basic_ios : public ios_base
|
||||
{
|
||||
public:
|
||||
// Types:
|
||||
};
|
||||
|
||||
06. Enumerators
|
||||
enum
|
||||
{
|
||||
space = _ISspace,
|
||||
print = _ISprint,
|
||||
cntrl = _IScntrl
|
||||
};
|
||||
-NOT-
|
||||
enum { space = _ISspace, print = _ISprint, cntrl = _IScntrl };
|
||||
|
||||
07. Member initialization lists
|
||||
All one line, separate from class name.
|
||||
|
||||
gribble::gribble()
|
||||
: _M_private_data(0), _M_more_stuff(0), _M_helper(0);
|
||||
{ }
|
||||
-NOT-
|
||||
gribble::gribble() : _M_private_data(0), _M_more_stuff(0), _M_helper(0);
|
||||
{ }
|
||||
|
||||
08. Try/Catch blocks
|
||||
try
|
||||
{
|
||||
//
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
//
|
||||
}
|
||||
-NOT-
|
||||
try {
|
||||
//
|
||||
} catch(...) {
|
||||
//
|
||||
}
|
||||
|
||||
09. Member functions declarations and definitions
|
||||
Keywords such as extern, static, export, explicit, inline, etc
|
||||
go on the line above the function name. Thus
|
||||
|
||||
virtual int
|
||||
foo()
|
||||
-NOT-
|
||||
virtual int foo()
|
||||
|
||||
Reason: GNU coding conventions dictate return types for functions
|
||||
are on a separate line than the function name and parameter list
|
||||
for definitions. For C++, where we have member functions that can
|
||||
be either inline definitions or declarations, keeping to this
|
||||
standard allows all member function names for a given class to be
|
||||
aligned to the same margin, increasing readibility.
|
||||
|
||||
|
||||
10. Invocation of member functions with "this->"
|
||||
For non-uglified names, use this->name to call the function.
|
||||
|
||||
this->sync()
|
||||
-NOT-
|
||||
sync()
|
||||
|
||||
Reason: Koenig lookup.
|
||||
|
||||
11. Namespaces
|
||||
namespace std
|
||||
{
|
||||
blah blah blah;
|
||||
} // namespace std
|
||||
|
||||
-NOT-
|
||||
|
||||
namespace std {
|
||||
blah blah blah;
|
||||
} // namespace std
|
||||
|
||||
12. Spacing under protected and private in class declarations:
|
||||
space above, none below
|
||||
ie
|
||||
|
||||
public:
|
||||
int foo;
|
||||
|
||||
-NOT-
|
||||
public:
|
||||
|
||||
int foo;
|
||||
|
||||
13. Spacing WRT return statements.
|
||||
no extra spacing before returns, no parenthesis
|
||||
ie
|
||||
|
||||
}
|
||||
return __ret;
|
||||
|
||||
-NOT-
|
||||
}
|
||||
|
||||
return __ret;
|
||||
|
||||
-NOT-
|
||||
|
||||
}
|
||||
return (__ret);
|
||||
|
||||
|
||||
14. Location of global variables.
|
||||
All global variables of class type, whether in the "user visable"
|
||||
space (e.g., cin) or the implementation namespace, must be defined
|
||||
as a character array with the appropriate alignment and then later
|
||||
re-initialized to the correct value.
|
||||
|
||||
This is due to startup issues on certain platforms, such as AIX.
|
||||
For more explanation and examples, see src/globals.cc. All such
|
||||
variables should be contained in that file, for simplicity.
|
||||
|
||||
15. Exception abstractions
|
||||
Use the exception abstractions found in functexcept.h, which allow
|
||||
C++ programmers to use this library with -fno-exceptions. (Even if
|
||||
that is rarely advisable, it's a necessary evil for backwards
|
||||
compatibility.)
|
||||
|
||||
16. Exception error messages
|
||||
All start with the name of the function where the exception is
|
||||
thrown, and then (optional) descriptive text is added. Example:
|
||||
|
||||
__throw_logic_error(__N("basic_string::_S_construct NULL not valid"));
|
||||
|
||||
Reason: The verbose terminate handler prints out exception::what(),
|
||||
as well as the typeinfo for the thrown exception. As this is the
|
||||
default terminate handler, by putting location info into the
|
||||
exception string, a very useful error message is printed out for
|
||||
uncaught exceptions. So useful, in fact, that non-programmers can
|
||||
give useful error messages, and programmers can intelligently
|
||||
speculate what went wrong without even using a debugger.
|
||||
|
||||
17. The doxygen style guide to comments is a separate document,
|
||||
see index.
|
||||
|
||||
The library currently has a mixture of GNU-C and modern C++ coding
|
||||
styles. The GNU C usages will be combed out gradually.
|
||||
|
||||
Name patterns:
|
||||
|
||||
For nonstandard names appearing in Standard headers, we are constrained
|
||||
to use names that begin with underscores. This is called "uglification".
|
||||
The convention is:
|
||||
|
||||
Local and argument names: __[a-z].*
|
||||
|
||||
Examples: __count __ix __s1
|
||||
|
||||
Type names and template formal-argument names: _[A-Z][^_].*
|
||||
|
||||
Examples: _Helper _CharT _N
|
||||
|
||||
Member data and function names: _M_.*
|
||||
|
||||
Examples: _M_num_elements _M_initialize ()
|
||||
|
||||
Static data members, constants, and enumerations: _S_.*
|
||||
|
||||
Examples: _S_max_elements _S_default_value
|
||||
|
||||
Don't use names in the same scope that differ only in the prefix,
|
||||
e.g. _S_top and _M_top. See BADNAMES for a list of forbidden names.
|
||||
(The most tempting of these seem to be and "_T" and "__sz".)
|
||||
|
||||
Names must never have "__" internally; it would confuse name
|
||||
unmanglers on some targets. Also, never use "__[0-9]", same reason.
|
||||
|
||||
--------------------------
|
||||
|
||||
[BY EXAMPLE]
|
||||
|
||||
#ifndef _HEADER_
|
||||
#define _HEADER_ 1
|
||||
|
||||
namespace std
|
||||
{
|
||||
class gribble
|
||||
{
|
||||
public:
|
||||
gribble() throw();
|
||||
|
||||
gribble(const gribble&);
|
||||
|
||||
explicit
|
||||
gribble(int __howmany);
|
||||
|
||||
gribble&
|
||||
operator=(const gribble&);
|
||||
|
||||
virtual
|
||||
~gribble() throw ();
|
||||
|
||||
// Start with a capital letter, end with a period.
|
||||
inline void
|
||||
public_member(const char* __arg) const;
|
||||
|
||||
// In-class function definitions should be restricted to one-liners.
|
||||
int
|
||||
one_line() { return 0 }
|
||||
|
||||
int
|
||||
two_lines(const char* arg)
|
||||
{ return strchr(arg, 'a'); }
|
||||
|
||||
inline int
|
||||
three_lines(); // inline, but defined below.
|
||||
|
||||
// Note indentation.
|
||||
template<typename _Formal_argument>
|
||||
void
|
||||
public_template() const throw();
|
||||
|
||||
template<typename _Iterator>
|
||||
void
|
||||
other_template();
|
||||
|
||||
private:
|
||||
class _Helper;
|
||||
|
||||
int _M_private_data;
|
||||
int _M_more_stuff;
|
||||
_Helper* _M_helper;
|
||||
int _M_private_function();
|
||||
|
||||
enum _Enum
|
||||
{
|
||||
_S_one,
|
||||
_S_two
|
||||
};
|
||||
|
||||
static void
|
||||
_S_initialize_library();
|
||||
};
|
||||
|
||||
// More-or-less-standard language features described by lack, not presence.
|
||||
# ifndef _G_NO_LONGLONG
|
||||
extern long long _G_global_with_a_good_long_name; // avoid globals!
|
||||
# endif
|
||||
|
||||
// Avoid in-class inline definitions, define separately;
|
||||
// likewise for member class definitions:
|
||||
inline int
|
||||
gribble::public_member() const
|
||||
{ int __local = 0; return __local; }
|
||||
|
||||
class gribble::_Helper
|
||||
{
|
||||
int _M_stuff;
|
||||
|
||||
friend class gribble;
|
||||
};
|
||||
}
|
||||
|
||||
// Names beginning with "__": only for arguments and
|
||||
// local variables; never use "__" in a type name, or
|
||||
// within any name; never use "__[0-9]".
|
||||
|
||||
#endif /* _HEADER_ */
|
||||
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<typename T> // notice: "typename", not "class", no space
|
||||
long_return_value_type<with_many, args>
|
||||
function_name(char* pointer, // "char *pointer" is wrong.
|
||||
char* argument,
|
||||
const Reference& ref)
|
||||
{
|
||||
// int a_local; /* wrong; see below. */
|
||||
if (test)
|
||||
{
|
||||
nested code
|
||||
}
|
||||
|
||||
int a_local = 0; // declare variable at first use.
|
||||
|
||||
// char a, b, *p; /* wrong */
|
||||
char a = 'a';
|
||||
char b = a + 1;
|
||||
char* c = "abc"; // each variable goes on its own line, always.
|
||||
|
||||
// except maybe here...
|
||||
for (unsigned i = 0, mask = 1; mask; ++i, mask <<= 1) {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
gribble::gribble()
|
||||
: _M_private_data(0), _M_more_stuff(0), _M_helper(0);
|
||||
{ }
|
||||
|
||||
inline int
|
||||
gribble::three_lines()
|
||||
{
|
||||
// doesn't fit in one line.
|
||||
}
|
||||
} // namespace std
|
||||
|
||||
|
||||
|
|
@ -1,340 +0,0 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Library General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Library General
|
||||
Public License instead of this License.
|
|
@ -1,355 +0,0 @@
|
|||
GNU Free Documentation License
|
||||
Version 1.1, March 2000
|
||||
|
||||
Copyright (C) 2000 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
0. PREAMBLE
|
||||
|
||||
The purpose of this License is to make a manual, textbook, or other
|
||||
written document "free" in the sense of freedom: to assure everyone
|
||||
the effective freedom to copy and redistribute it, with or without
|
||||
modifying it, either commercially or noncommercially. Secondarily,
|
||||
this License preserves for the author and publisher a way to get
|
||||
credit for their work, while not being considered responsible for
|
||||
modifications made by others.
|
||||
|
||||
This License is a kind of "copyleft", which means that derivative
|
||||
works of the document must themselves be free in the same sense. It
|
||||
complements the GNU General Public License, which is a copyleft
|
||||
license designed for free software.
|
||||
|
||||
We have designed this License in order to use it for manuals for free
|
||||
software, because free software needs free documentation: a free
|
||||
program should come with manuals providing the same freedoms that the
|
||||
software does. But this License is not limited to software manuals;
|
||||
it can be used for any textual work, regardless of subject matter or
|
||||
whether it is published as a printed book. We recommend this License
|
||||
principally for works whose purpose is instruction or reference.
|
||||
|
||||
|
||||
1. APPLICABILITY AND DEFINITIONS
|
||||
|
||||
This License applies to any manual or other work that contains a
|
||||
notice placed by the copyright holder saying it can be distributed
|
||||
under the terms of this License. The "Document", below, refers to any
|
||||
such manual or work. Any member of the public is a licensee, and is
|
||||
addressed as "you".
|
||||
|
||||
A "Modified Version" of the Document means any work containing the
|
||||
Document or a portion of it, either copied verbatim, or with
|
||||
modifications and/or translated into another language.
|
||||
|
||||
A "Secondary Section" is a named appendix or a front-matter section of
|
||||
the Document that deals exclusively with the relationship of the
|
||||
publishers or authors of the Document to the Document's overall subject
|
||||
(or to related matters) and contains nothing that could fall directly
|
||||
within that overall subject. (For example, if the Document is in part a
|
||||
textbook of mathematics, a Secondary Section may not explain any
|
||||
mathematics.) The relationship could be a matter of historical
|
||||
connection with the subject or with related matters, or of legal,
|
||||
commercial, philosophical, ethical or political position regarding
|
||||
them.
|
||||
|
||||
The "Invariant Sections" are certain Secondary Sections whose titles
|
||||
are designated, as being those of Invariant Sections, in the notice
|
||||
that says that the Document is released under this License.
|
||||
|
||||
The "Cover Texts" are certain short passages of text that are listed,
|
||||
as Front-Cover Texts or Back-Cover Texts, in the notice that says that
|
||||
the Document is released under this License.
|
||||
|
||||
A "Transparent" copy of the Document means a machine-readable copy,
|
||||
represented in a format whose specification is available to the
|
||||
general public, whose contents can be viewed and edited directly and
|
||||
straightforwardly with generic text editors or (for images composed of
|
||||
pixels) generic paint programs or (for drawings) some widely available
|
||||
drawing editor, and that is suitable for input to text formatters or
|
||||
for automatic translation to a variety of formats suitable for input
|
||||
to text formatters. A copy made in an otherwise Transparent file
|
||||
format whose markup has been designed to thwart or discourage
|
||||
subsequent modification by readers is not Transparent. A copy that is
|
||||
not "Transparent" is called "Opaque".
|
||||
|
||||
Examples of suitable formats for Transparent copies include plain
|
||||
ASCII without markup, Texinfo input format, LaTeX input format, SGML
|
||||
or XML using a publicly available DTD, and standard-conforming simple
|
||||
HTML designed for human modification. Opaque formats include
|
||||
PostScript, PDF, proprietary formats that can be read and edited only
|
||||
by proprietary word processors, SGML or XML for which the DTD and/or
|
||||
processing tools are not generally available, and the
|
||||
machine-generated HTML produced by some word processors for output
|
||||
purposes only.
|
||||
|
||||
The "Title Page" means, for a printed book, the title page itself,
|
||||
plus such following pages as are needed to hold, legibly, the material
|
||||
this License requires to appear in the title page. For works in
|
||||
formats which do not have any title page as such, "Title Page" means
|
||||
the text near the most prominent appearance of the work's title,
|
||||
preceding the beginning of the body of the text.
|
||||
|
||||
|
||||
2. VERBATIM COPYING
|
||||
|
||||
You may copy and distribute the Document in any medium, either
|
||||
commercially or noncommercially, provided that this License, the
|
||||
copyright notices, and the license notice saying this License applies
|
||||
to the Document are reproduced in all copies, and that you add no other
|
||||
conditions whatsoever to those of this License. You may not use
|
||||
technical measures to obstruct or control the reading or further
|
||||
copying of the copies you make or distribute. However, you may accept
|
||||
compensation in exchange for copies. If you distribute a large enough
|
||||
number of copies you must also follow the conditions in section 3.
|
||||
|
||||
You may also lend copies, under the same conditions stated above, and
|
||||
you may publicly display copies.
|
||||
|
||||
|
||||
3. COPYING IN QUANTITY
|
||||
|
||||
If you publish printed copies of the Document numbering more than 100,
|
||||
and the Document's license notice requires Cover Texts, you must enclose
|
||||
the copies in covers that carry, clearly and legibly, all these Cover
|
||||
Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
|
||||
the back cover. Both covers must also clearly and legibly identify
|
||||
you as the publisher of these copies. The front cover must present
|
||||
the full title with all words of the title equally prominent and
|
||||
visible. You may add other material on the covers in addition.
|
||||
Copying with changes limited to the covers, as long as they preserve
|
||||
the title of the Document and satisfy these conditions, can be treated
|
||||
as verbatim copying in other respects.
|
||||
|
||||
If the required texts for either cover are too voluminous to fit
|
||||
legibly, you should put the first ones listed (as many as fit
|
||||
reasonably) on the actual cover, and continue the rest onto adjacent
|
||||
pages.
|
||||
|
||||
If you publish or distribute Opaque copies of the Document numbering
|
||||
more than 100, you must either include a machine-readable Transparent
|
||||
copy along with each Opaque copy, or state in or with each Opaque copy
|
||||
a publicly-accessible computer-network location containing a complete
|
||||
Transparent copy of the Document, free of added material, which the
|
||||
general network-using public has access to download anonymously at no
|
||||
charge using public-standard network protocols. If you use the latter
|
||||
option, you must take reasonably prudent steps, when you begin
|
||||
distribution of Opaque copies in quantity, to ensure that this
|
||||
Transparent copy will remain thus accessible at the stated location
|
||||
until at least one year after the last time you distribute an Opaque
|
||||
copy (directly or through your agents or retailers) of that edition to
|
||||
the public.
|
||||
|
||||
It is requested, but not required, that you contact the authors of the
|
||||
Document well before redistributing any large number of copies, to give
|
||||
them a chance to provide you with an updated version of the Document.
|
||||
|
||||
|
||||
4. MODIFICATIONS
|
||||
|
||||
You may copy and distribute a Modified Version of the Document under
|
||||
the conditions of sections 2 and 3 above, provided that you release
|
||||
the Modified Version under precisely this License, with the Modified
|
||||
Version filling the role of the Document, thus licensing distribution
|
||||
and modification of the Modified Version to whoever possesses a copy
|
||||
of it. In addition, you must do these things in the Modified Version:
|
||||
|
||||
A. Use in the Title Page (and on the covers, if any) a title distinct
|
||||
from that of the Document, and from those of previous versions
|
||||
(which should, if there were any, be listed in the History section
|
||||
of the Document). You may use the same title as a previous version
|
||||
if the original publisher of that version gives permission.
|
||||
B. List on the Title Page, as authors, one or more persons or entities
|
||||
responsible for authorship of the modifications in the Modified
|
||||
Version, together with at least five of the principal authors of the
|
||||
Document (all of its principal authors, if it has less than five).
|
||||
C. State on the Title page the name of the publisher of the
|
||||
Modified Version, as the publisher.
|
||||
D. Preserve all the copyright notices of the Document.
|
||||
E. Add an appropriate copyright notice for your modifications
|
||||
adjacent to the other copyright notices.
|
||||
F. Include, immediately after the copyright notices, a license notice
|
||||
giving the public permission to use the Modified Version under the
|
||||
terms of this License, in the form shown in the Addendum below.
|
||||
G. Preserve in that license notice the full lists of Invariant Sections
|
||||
and required Cover Texts given in the Document's license notice.
|
||||
H. Include an unaltered copy of this License.
|
||||
I. Preserve the section entitled "History", and its title, and add to
|
||||
it an item stating at least the title, year, new authors, and
|
||||
publisher of the Modified Version as given on the Title Page. If
|
||||
there is no section entitled "History" in the Document, create one
|
||||
stating the title, year, authors, and publisher of the Document as
|
||||
given on its Title Page, then add an item describing the Modified
|
||||
Version as stated in the previous sentence.
|
||||
J. Preserve the network location, if any, given in the Document for
|
||||
public access to a Transparent copy of the Document, and likewise
|
||||
the network locations given in the Document for previous versions
|
||||
it was based on. These may be placed in the "History" section.
|
||||
You may omit a network location for a work that was published at
|
||||
least four years before the Document itself, or if the original
|
||||
publisher of the version it refers to gives permission.
|
||||
K. In any section entitled "Acknowledgements" or "Dedications",
|
||||
preserve the section's title, and preserve in the section all the
|
||||
substance and tone of each of the contributor acknowledgements
|
||||
and/or dedications given therein.
|
||||
L. Preserve all the Invariant Sections of the Document,
|
||||
unaltered in their text and in their titles. Section numbers
|
||||
or the equivalent are not considered part of the section titles.
|
||||
M. Delete any section entitled "Endorsements". Such a section
|
||||
may not be included in the Modified Version.
|
||||
N. Do not retitle any existing section as "Endorsements"
|
||||
or to conflict in title with any Invariant Section.
|
||||
|
||||
If the Modified Version includes new front-matter sections or
|
||||
appendices that qualify as Secondary Sections and contain no material
|
||||
copied from the Document, you may at your option designate some or all
|
||||
of these sections as invariant. To do this, add their titles to the
|
||||
list of Invariant Sections in the Modified Version's license notice.
|
||||
These titles must be distinct from any other section titles.
|
||||
|
||||
You may add a section entitled "Endorsements", provided it contains
|
||||
nothing but endorsements of your Modified Version by various
|
||||
parties--for example, statements of peer review or that the text has
|
||||
been approved by an organization as the authoritative definition of a
|
||||
standard.
|
||||
|
||||
You may add a passage of up to five words as a Front-Cover Text, and a
|
||||
passage of up to 25 words as a Back-Cover Text, to the end of the list
|
||||
of Cover Texts in the Modified Version. Only one passage of
|
||||
Front-Cover Text and one of Back-Cover Text may be added by (or
|
||||
through arrangements made by) any one entity. If the Document already
|
||||
includes a cover text for the same cover, previously added by you or
|
||||
by arrangement made by the same entity you are acting on behalf of,
|
||||
you may not add another; but you may replace the old one, on explicit
|
||||
permission from the previous publisher that added the old one.
|
||||
|
||||
The author(s) and publisher(s) of the Document do not by this License
|
||||
give permission to use their names for publicity for or to assert or
|
||||
imply endorsement of any Modified Version.
|
||||
|
||||
|
||||
5. COMBINING DOCUMENTS
|
||||
|
||||
You may combine the Document with other documents released under this
|
||||
License, under the terms defined in section 4 above for modified
|
||||
versions, provided that you include in the combination all of the
|
||||
Invariant Sections of all of the original documents, unmodified, and
|
||||
list them all as Invariant Sections of your combined work in its
|
||||
license notice.
|
||||
|
||||
The combined work need only contain one copy of this License, and
|
||||
multiple identical Invariant Sections may be replaced with a single
|
||||
copy. If there are multiple Invariant Sections with the same name but
|
||||
different contents, make the title of each such section unique by
|
||||
adding at the end of it, in parentheses, the name of the original
|
||||
author or publisher of that section if known, or else a unique number.
|
||||
Make the same adjustment to the section titles in the list of
|
||||
Invariant Sections in the license notice of the combined work.
|
||||
|
||||
In the combination, you must combine any sections entitled "History"
|
||||
in the various original documents, forming one section entitled
|
||||
"History"; likewise combine any sections entitled "Acknowledgements",
|
||||
and any sections entitled "Dedications". You must delete all sections
|
||||
entitled "Endorsements."
|
||||
|
||||
|
||||
6. COLLECTIONS OF DOCUMENTS
|
||||
|
||||
You may make a collection consisting of the Document and other documents
|
||||
released under this License, and replace the individual copies of this
|
||||
License in the various documents with a single copy that is included in
|
||||
the collection, provided that you follow the rules of this License for
|
||||
verbatim copying of each of the documents in all other respects.
|
||||
|
||||
You may extract a single document from such a collection, and distribute
|
||||
it individually under this License, provided you insert a copy of this
|
||||
License into the extracted document, and follow this License in all
|
||||
other respects regarding verbatim copying of that document.
|
||||
|
||||
|
||||
7. AGGREGATION WITH INDEPENDENT WORKS
|
||||
|
||||
A compilation of the Document or its derivatives with other separate
|
||||
and independent documents or works, in or on a volume of a storage or
|
||||
distribution medium, does not as a whole count as a Modified Version
|
||||
of the Document, provided no compilation copyright is claimed for the
|
||||
compilation. Such a compilation is called an "aggregate", and this
|
||||
License does not apply to the other self-contained works thus compiled
|
||||
with the Document, on account of their being thus compiled, if they
|
||||
are not themselves derivative works of the Document.
|
||||
|
||||
If the Cover Text requirement of section 3 is applicable to these
|
||||
copies of the Document, then if the Document is less than one quarter
|
||||
of the entire aggregate, the Document's Cover Texts may be placed on
|
||||
covers that surround only the Document within the aggregate.
|
||||
Otherwise they must appear on covers around the whole aggregate.
|
||||
|
||||
|
||||
8. TRANSLATION
|
||||
|
||||
Translation is considered a kind of modification, so you may
|
||||
distribute translations of the Document under the terms of section 4.
|
||||
Replacing Invariant Sections with translations requires special
|
||||
permission from their copyright holders, but you may include
|
||||
translations of some or all Invariant Sections in addition to the
|
||||
original versions of these Invariant Sections. You may include a
|
||||
translation of this License provided that you also include the
|
||||
original English version of this License. In case of a disagreement
|
||||
between the translation and the original English version of this
|
||||
License, the original English version will prevail.
|
||||
|
||||
|
||||
9. TERMINATION
|
||||
|
||||
You may not copy, modify, sublicense, or distribute the Document except
|
||||
as expressly provided for under this License. Any other attempt to
|
||||
copy, modify, sublicense or distribute the Document is void, and will
|
||||
automatically terminate your rights under this License. However,
|
||||
parties who have received copies, or rights, from you under this
|
||||
License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
|
||||
10. FUTURE REVISIONS OF THIS LICENSE
|
||||
|
||||
The Free Software Foundation may publish new, revised versions
|
||||
of the GNU Free Documentation License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns. See
|
||||
http://www.gnu.org/copyleft/.
|
||||
|
||||
Each version of the License is given a distinguishing version number.
|
||||
If the Document specifies that a particular numbered version of this
|
||||
License "or any later version" applies to it, you have the option of
|
||||
following the terms and conditions either of that specified version or
|
||||
of any later version that has been published (not as a draft) by the
|
||||
Free Software Foundation. If the Document does not specify a version
|
||||
number of this License, you may choose any version ever published (not
|
||||
as a draft) by the Free Software Foundation.
|
||||
|
||||
|
||||
ADDENDUM: How to use this License for your documents
|
||||
|
||||
To use this License in a document you have written, include a copy of
|
||||
the License in the document and put the following copyright and
|
||||
license notices just after the title page:
|
||||
|
||||
Copyright (c) YEAR YOUR NAME.
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.1
|
||||
or any later version published by the Free Software Foundation;
|
||||
with the Invariant Sections being LIST THEIR TITLES, with the
|
||||
Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST.
|
||||
A copy of the license is included in the section entitled "GNU
|
||||
Free Documentation License".
|
||||
|
||||
If you have no Invariant Sections, write "with no Invariant Sections"
|
||||
instead of saying which ones are invariant. If you have no
|
||||
Front-Cover Texts, write "no Front-Cover Texts" instead of
|
||||
"Front-Cover Texts being LIST"; likewise for Back-Cover Texts.
|
||||
|
||||
If your document contains nontrivial examples of program code, we
|
||||
recommend releasing these examples in parallel under your choice of
|
||||
free software license, such as the GNU General Public License,
|
||||
to permit their use in free software.
|
|
@ -1,859 +0,0 @@
|
|||
|
||||
Standard C++ Library Design Document
|
||||
------------------------------------
|
||||
|
||||
This is an overview of libstdc++-v3, with particular attention
|
||||
to projects to be done and how they fit into the whole.
|
||||
|
||||
The Library
|
||||
-----------
|
||||
|
||||
This paper is covers two major areas:
|
||||
|
||||
- Features and policies not mentioned in the standard that
|
||||
the quality of the library implementation depends on, including
|
||||
extensions and "implementation-defined" features;
|
||||
|
||||
- Plans for required but unimplemented library features and
|
||||
optimizations to them.
|
||||
|
||||
Overhead
|
||||
--------
|
||||
|
||||
The standard defines a large library, much larger than the standard
|
||||
C library. A naive implementation would suffer substantial overhead
|
||||
in compile time, executable size, and speed, rendering it unusable
|
||||
in many (particularly embedded) applications. The alternative demands
|
||||
care in construction, and some compiler support, but there is no
|
||||
need for library subsets.
|
||||
|
||||
What are the sources of this overhead? There are four main causes:
|
||||
|
||||
- The library is specified almost entirely as templates, which
|
||||
with current compilers must be included in-line, resulting in
|
||||
very slow builds as tens or hundreds of thousands of lines
|
||||
of function definitions are read for each user source file.
|
||||
Indeed, the entire SGI STL, as well as the dos Reis valarray,
|
||||
are provided purely as header files, largely for simplicity in
|
||||
porting. Iostream/locale is (or will be) as large again.
|
||||
|
||||
- The library is very flexible, specifying a multitude of hooks
|
||||
where users can insert their own code in place of defaults.
|
||||
When these hooks are not used, any time and code expended to
|
||||
support that flexibility is wasted.
|
||||
|
||||
- Templates are often described as causing to "code bloat". In
|
||||
practice, this refers (when it refers to anything real) to several
|
||||
independent processes. First, when a class template is manually
|
||||
instantiated in its entirely, current compilers place the definitions
|
||||
for all members in a single object file, so that a program linking
|
||||
to one member gets definitions of all. Second, template functions
|
||||
which do not actually depend on the template argument are, under
|
||||
current compilers, generated anew for each instantiation, rather
|
||||
than being shared with other instantiations. Third, some of the
|
||||
flexibility mentioned above comes from virtual functions (both in
|
||||
regular classes and template classes) which current linkers add
|
||||
to the executable file even when they manifestly cannot be called.
|
||||
|
||||
- The library is specified to use a language feature, exceptions,
|
||||
which in the current gcc compiler ABI imposes a run time and
|
||||
code space cost to handle the possibility of exceptions even when
|
||||
they are not used. Under the new ABI (accessed with -fnew-abi),
|
||||
there is a space overhead and a small reduction in code efficiency
|
||||
resulting from lost optimization opportunities associated with
|
||||
non-local branches associated with exceptions.
|
||||
|
||||
What can be done to eliminate this overhead? A variety of coding
|
||||
techniques, and compiler, linker and library improvements and
|
||||
extensions may be used, as covered below. Most are not difficult,
|
||||
and some are already implemented in varying degrees.
|
||||
|
||||
Overhead: Compilation Time
|
||||
--------------------------
|
||||
|
||||
Providing "ready-instantiated" template code in object code archives
|
||||
allows us to avoid generating and optimizing template instantiations
|
||||
in each compilation unit which uses them. However, the number of such
|
||||
instantiations that are useful to provide is limited, and anyway this
|
||||
is not enough, by itself, to minimize compilation time. In particular,
|
||||
it does not reduce time spent parsing conforming headers.
|
||||
|
||||
Quicker header parsing will depend on library extensions and compiler
|
||||
improvements. One approach is some variation on the techniques
|
||||
previously marketed as "pre-compiled headers", now standardized as
|
||||
support for the "export" keyword. "Exported" template definitions
|
||||
can be placed (once) in a "repository" -- really just a library, but
|
||||
of template definitions rather than object code -- to be drawn upon
|
||||
at link time when an instantiation is needed, rather than placed in
|
||||
header files to be parsed along with every compilation unit.
|
||||
|
||||
Until "export" is implemented we can put some of the lengthy template
|
||||
definitions in #if guards or alternative headers so that users can skip
|
||||
over the the full definitions when they need only the ready-instantiated
|
||||
specializations.
|
||||
|
||||
To be precise, this means that certain headers which define
|
||||
templates which users normally use only for certain arguments
|
||||
can be instrumented to avoid exposing the template definitions
|
||||
to the compiler unless a macro is defined. For example, in
|
||||
<string>, we might have:
|
||||
|
||||
template <class _CharT, ... > class basic_string {
|
||||
... // member declarations
|
||||
};
|
||||
... // operator declarations
|
||||
|
||||
#ifdef _STRICT_ISO_
|
||||
# if _G_NO_TEMPLATE_EXPORT
|
||||
# include <bits/std_locale.h> // headers needed by definitions
|
||||
# ...
|
||||
# include <bits/string.tcc> // member and global template definitions.
|
||||
# endif
|
||||
#endif
|
||||
|
||||
Users who compile without specifying a strict-ISO-conforming flag
|
||||
would not see many of the template definitions they now see, and rely
|
||||
instead on ready-instantiated specializations in the library. This
|
||||
technique would be useful for the following substantial components:
|
||||
string, locale/iostreams, valarray. It would *not* be useful or
|
||||
usable with the following: containers, algorithms, iterators,
|
||||
allocator. Since these constitute a large (though decreasing)
|
||||
fraction of the library, the benefit the technique offers is
|
||||
limited.
|
||||
|
||||
The language specifies the semantics of the "export" keyword, but
|
||||
the gcc compiler does not yet support it. When it does, problems
|
||||
with large template inclusions can largely disappear, given some
|
||||
minor library reorganization, along with the need for the apparatus
|
||||
described above.
|
||||
|
||||
Overhead: Flexibility Cost
|
||||
--------------------------
|
||||
|
||||
The library offers many places where users can specify operations
|
||||
to be performed by the library in place of defaults. Sometimes
|
||||
this seems to require that the library use a more-roundabout, and
|
||||
possibly slower, way to accomplish the default requirements than
|
||||
would be used otherwise.
|
||||
|
||||
The primary protection against this overhead is thorough compiler
|
||||
optimization, to crush out layers of inline function interfaces.
|
||||
Kuck & Associates has demonstrated the practicality of this kind
|
||||
of optimization.
|
||||
|
||||
The second line of defense against this overhead is explicit
|
||||
specialization. By defining helper function templates, and writing
|
||||
specialized code for the default case, overhead can be eliminated
|
||||
for that case without sacrificing flexibility. This takes full
|
||||
advantage of any ability of the optimizer to crush out degenerate
|
||||
code.
|
||||
|
||||
The library specifies many virtual functions which current linkers
|
||||
load even when they cannot be called. Some minor improvements to the
|
||||
compiler and to ld would eliminate any such overhead by simply
|
||||
omitting virtual functions that the complete program does not call.
|
||||
A prototype of this work has already been done. For targets where
|
||||
GNU ld is not used, a "pre-linker" could do the same job.
|
||||
|
||||
The main areas in the standard interface where user flexibility
|
||||
can result in overhead are:
|
||||
|
||||
- Allocators: Containers are specified to use user-definable
|
||||
allocator types and objects, making tuning for the container
|
||||
characteristics tricky.
|
||||
|
||||
- Locales: the standard specifies locale objects used to implement
|
||||
iostream operations, involving many virtual functions which use
|
||||
streambuf iterators.
|
||||
|
||||
- Algorithms and containers: these may be instantiated on any type,
|
||||
frequently duplicating code for identical operations.
|
||||
|
||||
- Iostreams and strings: users are permitted to use these on their
|
||||
own types, and specify the operations the stream must use on these
|
||||
types.
|
||||
|
||||
Note that these sources of overhead are _avoidable_. The techniques
|
||||
to avoid them are covered below.
|
||||
|
||||
Code Bloat
|
||||
----------
|
||||
|
||||
In the SGI STL, and in some other headers, many of the templates
|
||||
are defined "inline" -- either explicitly or by their placement
|
||||
in class definitions -- which should not be inline. This is a
|
||||
source of code bloat. Matt had remarked that he was relying on
|
||||
the compiler to recognize what was too big to benefit from inlining,
|
||||
and generate it out-of-line automatically. However, this also can
|
||||
result in code bloat except where the linker can eliminate the extra
|
||||
copies.
|
||||
|
||||
Fixing these cases will require an audit of all inline functions
|
||||
defined in the library to determine which merit inlining, and moving
|
||||
the rest out of line. This is an issue mainly in chapters 23, 25, and
|
||||
27. Of course it can be done incrementally, and we should generally
|
||||
accept patches that move large functions out of line and into ".tcc"
|
||||
files, which can later be pulled into a repository. Compiler/linker
|
||||
improvements to recognize very large inline functions and move them
|
||||
out-of-line, but shared among compilation units, could make this
|
||||
work unnecessary.
|
||||
|
||||
Pre-instantiating template specializations currently produces large
|
||||
amounts of dead code which bloats statically linked programs. The
|
||||
current state of the static library, libstdc++.a, is intolerable on
|
||||
this account, and will fuel further confused speculation about a need
|
||||
for a library "subset". A compiler improvement that treats each
|
||||
instantiated function as a separate object file, for linking purposes,
|
||||
would be one solution to this problem. An alternative would be to
|
||||
split up the manual instantiation files into dozens upon dozens of
|
||||
little files, each compiled separately, but an abortive attempt at
|
||||
this was done for <string> and, though it is far from complete, it
|
||||
is already a nuisance. A better interim solution (just until we have
|
||||
"export") is badly needed.
|
||||
|
||||
When building a shared library, the current compiler/linker cannot
|
||||
automatically generate the instantiatiations needed. This creates a
|
||||
miserable situation; it means any time something is changed in the
|
||||
library, before a shared library can be built someone must manually
|
||||
copy the declarations of all templates that are needed by other parts
|
||||
of the library to an "instantiation" file, and add it to the build
|
||||
system to be compiled and linked to the library. This process is
|
||||
readily automated, and should be automated as soon as possible.
|
||||
Users building their own shared libraries experience identical
|
||||
frustrations.
|
||||
|
||||
Sharing common aspects of template definitions among instantiations
|
||||
can radically reduce code bloat. The compiler could help a great
|
||||
deal here by recognizing when a function depends on nothing about
|
||||
a template parameter, or only on its size, and giving the resulting
|
||||
function a link-name "equate" that allows it to be shared with other
|
||||
instantiations. Implementation code could take advantage of the
|
||||
capability by factoring out code that does not depend on the template
|
||||
argument into separate functions to be merged by the compiler.
|
||||
|
||||
Until such a compiler optimization is implemented, much can be done
|
||||
manually (if tediously) in this direction. One such optimization is
|
||||
to derive class templates from non-template classes, and move as much
|
||||
implementation as possible into the base class. Another is to partial-
|
||||
specialize certain common instantiations, such as vector<T*>, to share
|
||||
code for instantiations on all types T. While these techniques work,
|
||||
they are far from the complete solution that a compiler improvement
|
||||
would afford.
|
||||
|
||||
Overhead: Expensive Language Features
|
||||
-------------------------------------
|
||||
|
||||
The main "expensive" language feature used in the standard library
|
||||
is exception support, which requires compiling in cleanup code with
|
||||
static table data to locate it, and linking in library code to use
|
||||
the table. For small embedded programs the amount of such library
|
||||
code and table data is assumed by some to be excessive. Under the
|
||||
"new" ABI this perception is generally exaggerated, although in some
|
||||
cases it may actually be excessive.
|
||||
|
||||
To implement a library which does not use exceptions directly is
|
||||
not difficult given minor compiler support (to "turn off" exceptions
|
||||
and ignore exception constructs), and results in no great library
|
||||
maintenance difficulties. To be precise, given "-fno-exceptions",
|
||||
the compiler should treat "try" blocks as ordinary blocks, and
|
||||
"catch" blocks as dead code to ignore or eliminate. Compiler
|
||||
support is not strictly necessary, except in the case of "function
|
||||
try blocks"; otherwise the following macros almost suffice:
|
||||
|
||||
#define throw(X)
|
||||
#define try if (true)
|
||||
#define catch(X) else if (false)
|
||||
|
||||
However, there may be a need to use function try blocks in the
|
||||
library implementation, and use of macros in this way can make
|
||||
correct diagnostics impossible. Furthermore, use of this scheme
|
||||
would require the library to call a function to re-throw exceptions
|
||||
from a try block. Implementing the above semantics in the compiler
|
||||
is preferable.
|
||||
|
||||
Given the support above (however implemented) it only remains to
|
||||
replace code that "throws" with a call to a well-documented "handler"
|
||||
function in a separate compilation unit which may be replaced by
|
||||
the user. The main source of exceptions that would be difficult
|
||||
for users to avoid is memory allocation failures, but users can
|
||||
define their own memory allocation primitives that never throw.
|
||||
Otherwise, the complete list of such handlers, and which library
|
||||
functions may call them, would be needed for users to be able to
|
||||
implement the necessary substitutes. (Fortunately, they have the
|
||||
source code.)
|
||||
|
||||
Opportunities
|
||||
-------------
|
||||
|
||||
The template capabilities of C++ offer enormous opportunities for
|
||||
optimizing common library operations, well beyond what would be
|
||||
considered "eliminating overhead". In particular, many operations
|
||||
done in Glibc with macros that depend on proprietary language
|
||||
extensions can be implemented in pristine Standard C++. For example,
|
||||
the chapter 25 algorithms, and even C library functions such as strchr,
|
||||
can be specialized for the case of static arrays of known (small) size.
|
||||
|
||||
Detailed optimization opportunities are identified below where
|
||||
the component where they would appear is discussed. Of course new
|
||||
opportunities will be identified during implementation.
|
||||
|
||||
Unimplemented Required Library Features
|
||||
---------------------------------------
|
||||
|
||||
The standard specifies hundreds of components, grouped broadly by
|
||||
chapter. These are listed in excruciating detail in the CHECKLIST
|
||||
file.
|
||||
|
||||
17 general
|
||||
18 support
|
||||
19 diagnostics
|
||||
20 utilities
|
||||
21 string
|
||||
22 locale
|
||||
23 containers
|
||||
24 iterators
|
||||
25 algorithms
|
||||
26 numerics
|
||||
27 iostreams
|
||||
Annex D backward compatibility
|
||||
|
||||
Anyone participating in implementation of the library should obtain
|
||||
a copy of the standard, ISO 14882. People in the U.S. can obtain an
|
||||
electronic copy for US$18 from ANSI's web site. Those from other
|
||||
countries should visit http://www.iso.ch/ to find out the location
|
||||
of their country's representation in ISO, in order to know who can
|
||||
sell them a copy.
|
||||
|
||||
The emphasis in the following sections is on unimplemented features
|
||||
and optimization opportunities.
|
||||
|
||||
Chapter 17 General
|
||||
-------------------
|
||||
|
||||
Chapter 17 concerns overall library requirements.
|
||||
|
||||
The standard doesn't mention threads. A multi-thread (MT) extension
|
||||
primarily affects operators new and delete (18), allocator (20),
|
||||
string (21), locale (22), and iostreams (27). The common underlying
|
||||
support needed for this is discussed under chapter 20.
|
||||
|
||||
The standard requirements on names from the C headers create a
|
||||
lot of work, mostly done. Names in the C headers must be visible
|
||||
in the std:: and sometimes the global namespace; the names in the
|
||||
two scopes must refer to the same object. More stringent is that
|
||||
Koenig lookup implies that any types specified as defined in std::
|
||||
really are defined in std::. Names optionally implemented as
|
||||
macros in C cannot be macros in C++. (An overview may be read at
|
||||
<http://www.cantrip.org/cheaders.html>). The scripts "inclosure"
|
||||
and "mkcshadow", and the directories shadow/ and cshadow/, are the
|
||||
beginning of an effort to conform in this area.
|
||||
|
||||
A correct conforming definition of C header names based on underlying
|
||||
C library headers, and practical linking of conforming namespaced
|
||||
customer code with third-party C libraries depends ultimately on
|
||||
an ABI change, allowing namespaced C type names to be mangled into
|
||||
type names as if they were global, somewhat as C function names in a
|
||||
namespace, or C++ global variable names, are left unmangled. Perhaps
|
||||
another "extern" mode, such as 'extern "C-global"' would be an
|
||||
appropriate place for such type definitions. Such a type would
|
||||
affect mangling as follows:
|
||||
|
||||
namespace A {
|
||||
struct X {};
|
||||
extern "C-global" { // or maybe just 'extern "C"'
|
||||
struct Y {};
|
||||
};
|
||||
}
|
||||
void f(A::X*); // mangles to f__FPQ21A1X
|
||||
void f(A::Y*); // mangles to f__FP1Y
|
||||
|
||||
(It may be that this is really the appropriate semantics for regular
|
||||
'extern "C"', and 'extern "C-global"', as an extension, would not be
|
||||
necessary.) This would allow functions declared in non-standard C headers
|
||||
(and thus fixable by neither us nor users) to link properly with functions
|
||||
declared using C types defined in properly-namespaced headers. The
|
||||
problem this solves is that C headers (which C++ programmers do persist
|
||||
in using) frequently forward-declare C struct tags without including
|
||||
the header where the type is defined, as in
|
||||
|
||||
struct tm;
|
||||
void munge(tm*);
|
||||
|
||||
Without some compiler accommodation, munge cannot be called by correct
|
||||
C++ code using a pointer to a correctly-scoped tm* value.
|
||||
|
||||
The current C headers use the preprocessor extension "#include_next",
|
||||
which the compiler complains about when run "-pedantic".
|
||||
(Incidentally, it appears that "-fpedantic" is currently ignored,
|
||||
probably a bug.) The solution in the C compiler is to use
|
||||
"-isystem" rather than "-I", but unfortunately in g++ this seems
|
||||
also to wrap the whole header in an 'extern "C"' block, so it's
|
||||
unusable for C++ headers. The correct solution appears to be to
|
||||
allow the various special include-directory options, if not given
|
||||
an argument, to affect subsequent include-directory options additively,
|
||||
so that if one said
|
||||
|
||||
-pedantic -iprefix $(prefix) \
|
||||
-idirafter -ino-pedantic -ino-extern-c -iwithprefix -I g++-v3 \
|
||||
-iwithprefix -I g++-v3/ext
|
||||
|
||||
the compiler would search $(prefix)/g++-v3 and not report
|
||||
pedantic warnings for files found there, but treat files in
|
||||
$(prefix)/g++-v3/ext pedantically. (The undocumented semantics
|
||||
of "-isystem" in g++ stink. Can they be rescinded? If not it
|
||||
must be replaced with something more rationally behaved.)
|
||||
|
||||
All the C headers need the treatment above; in the standard these
|
||||
headers are mentioned in various chapters. Below, I have only
|
||||
mentioned those that present interesting implementation issues.
|
||||
|
||||
The components identified as "mostly complete", below, have not been
|
||||
audited for conformance. In many cases where the library passes
|
||||
conformance tests we have non-conforming extensions that must be
|
||||
wrapped in #if guards for "pedantic" use, and in some cases renamed
|
||||
in a conforming way for continued use in the implementation regardless
|
||||
of conformance flags.
|
||||
|
||||
The STL portion of the library still depends on a header
|
||||
stl/bits/stl_config.h full of #ifdef clauses. This apparatus
|
||||
should be replaced with autoconf/automake machinery.
|
||||
|
||||
The SGI STL defines a type_traits<> template, specialized for
|
||||
many types in their code including the built-in numeric and
|
||||
pointer types and some library types, to direct optimizations of
|
||||
standard functions. The SGI compiler has been extended to generate
|
||||
specializations of this template automatically for user types,
|
||||
so that use of STL templates on user types can take advantage of
|
||||
these optimizations. Specializations for other, non-STL, types
|
||||
would make more optimizations possible, but extending the gcc
|
||||
compiler in the same way would be much better. Probably the next
|
||||
round of standardization will ratify this, but probably with
|
||||
changes, so it probably should be renamed to place it in the
|
||||
implementation namespace.
|
||||
|
||||
The SGI STL also defines a large number of extensions visible in
|
||||
standard headers. (Other extensions that appear in separate headers
|
||||
have been sequestered in subdirectories ext/ and backward/.) All
|
||||
these extensions should be moved to other headers where possible,
|
||||
and in any case wrapped in a namespace (not std!), and (where kept
|
||||
in a standard header) girded about with macro guards. Some cannot be
|
||||
moved out of standard headers because they are used to implement
|
||||
standard features. The canonical method for accommodating these
|
||||
is to use a protected name, aliased in macro guards to a user-space
|
||||
name. Unfortunately C++ offers no satisfactory template typedef
|
||||
mechanism, so very ad-hoc and unsatisfactory aliasing must be used
|
||||
instead.
|
||||
|
||||
Implementation of a template typedef mechanism should have the highest
|
||||
priority among possible extensions, on the same level as implementation
|
||||
of the template "export" feature.
|
||||
|
||||
Chapter 18 Language support
|
||||
----------------------------
|
||||
|
||||
Headers: <limits> <new> <typeinfo> <exception>
|
||||
C headers: <cstddef> <climits> <cfloat> <cstdarg> <csetjmp>
|
||||
<ctime> <csignal> <cstdlib> (also 21, 25, 26)
|
||||
|
||||
This defines the built-in exceptions, rtti, numeric_limits<>,
|
||||
operator new and delete. Much of this is provided by the
|
||||
compiler in its static runtime library.
|
||||
|
||||
Work to do includes defining numeric_limits<> specializations in
|
||||
separate files for all target architectures. Values for integer types
|
||||
except for bool and wchar_t are readily obtained from the C header
|
||||
<limits.h>, but values for the remaining numeric types (bool, wchar_t,
|
||||
float, double, long double) must be entered manually. This is
|
||||
largely dog work except for those members whose values are not
|
||||
easily deduced from available documentation. Also, this involves
|
||||
some work in target configuration to identify the correct choice of
|
||||
file to build against and to install.
|
||||
|
||||
The definitions of the various operators new and delete must be
|
||||
made thread-safe, which depends on a portable exclusion mechanism,
|
||||
discussed under chapter 20. Of course there is always plenty of
|
||||
room for improvements to the speed of operators new and delete.
|
||||
|
||||
<cstdarg>, in Glibc, defines some macros that gcc does not allow to
|
||||
be wrapped into an inline function. Probably this header will demand
|
||||
attention whenever a new target is chosen. The functions atexit(),
|
||||
exit(), and abort() in cstdlib have different semantics in C++, so
|
||||
must be re-implemented for C++.
|
||||
|
||||
Chapter 19 Diagnostics
|
||||
-----------------------
|
||||
|
||||
Headers: <stdexcept>
|
||||
C headers: <cassert> <cerrno>
|
||||
|
||||
This defines the standard exception objects, which are "mostly complete".
|
||||
Cygnus has a version, and now SGI provides a slightly different one.
|
||||
It makes little difference which we use.
|
||||
|
||||
The C global name "errno", which C allows to be a variable or a macro,
|
||||
is required in C++ to be a macro. For MT it must typically result in
|
||||
a function call.
|
||||
|
||||
Chapter 20 Utilities
|
||||
---------------------
|
||||
Headers: <utility> <functional> <memory>
|
||||
C header: <ctime> (also in 18)
|
||||
|
||||
SGI STL provides "mostly complete" versions of all the components
|
||||
defined in this chapter. However, the auto_ptr<> implementation
|
||||
is known to be wrong. Furthermore, the standard definition of it
|
||||
is known to be unimplementable as written. A minor change to the
|
||||
standard would fix it, and auto_ptr<> should be adjusted to match.
|
||||
|
||||
Multi-threading affects the allocator implementation, and there must
|
||||
be configuration/installation choices for different users' MT
|
||||
requirements. Anyway, users will want to tune allocator options
|
||||
to support different target conditions, MT or no.
|
||||
|
||||
The primitives used for MT implementation should be exposed, as an
|
||||
extension, for users' own work. We need cross-CPU "mutex" support,
|
||||
multi-processor shared-memory atomic integer operations, and single-
|
||||
processor uninterruptible integer operations, and all three configurable
|
||||
to be stubbed out for non-MT use, or to use an appropriately-loaded
|
||||
dynamic library for the actual runtime environment, or statically
|
||||
compiled in for cases where the target architecture is known.
|
||||
|
||||
Chapter 21 String
|
||||
------------------
|
||||
Headers: <string>
|
||||
C headers: <cctype> <cwctype> <cstring> <cwchar> (also in 27)
|
||||
<cstdlib> (also in 18, 25, 26)
|
||||
|
||||
We have "mostly-complete" char_traits<> implementations. Many of the
|
||||
char_traits<char> operations might be optimized further using existing
|
||||
proprietary language extensions.
|
||||
|
||||
We have a "mostly-complete" basic_string<> implementation. The work
|
||||
to manually instantiate char and wchar_t specializations in object
|
||||
files to improve link-time behavior is extremely unsatisfactory,
|
||||
literally tripling library-build time with no commensurate improvement
|
||||
in static program link sizes. It must be redone. (Similar work is
|
||||
needed for some components in chapters 22 and 27.)
|
||||
|
||||
Other work needed for strings is MT-safety, as discussed under the
|
||||
chapter 20 heading.
|
||||
|
||||
The standard C type mbstate_t from <cwchar> and used in char_traits<>
|
||||
must be different in C++ than in C, because in C++ the default constructor
|
||||
value mbstate_t() must be the "base" or "ground" sequence state.
|
||||
(According to the likely resolution of a recently raised Core issue,
|
||||
this may become unnecessary. However, there are other reasons to
|
||||
use a state type not as limited as whatever the C library provides.)
|
||||
If we might want to provide conversions from (e.g.) internally-
|
||||
represented EUC-wide to externally-represented Unicode, or vice-
|
||||
versa, the mbstate_t we choose will need to be more accommodating
|
||||
than what might be provided by an underlying C library.
|
||||
|
||||
There remain some basic_string template-member functions which do
|
||||
not overload properly with their non-template brethren. The infamous
|
||||
hack akin to what was done in vector<> is needed, to conform to
|
||||
23.1.1 para 10. The CHECKLIST items for basic_string marked 'X',
|
||||
or incomplete, are so marked for this reason.
|
||||
|
||||
Replacing the string iterators, which currently are simple character
|
||||
pointers, with class objects would greatly increase the safety of the
|
||||
client interface, and also permit a "debug" mode in which range,
|
||||
ownership, and validity are rigorously checked. The current use of
|
||||
raw pointers as string iterators is evil. vector<> iterators need the
|
||||
same treatment. Note that the current implementation freely mixes
|
||||
pointers and iterators, and that must be fixed before safer iterators
|
||||
can be introduced.
|
||||
|
||||
Some of the functions in <cstring> are different from the C version.
|
||||
generally overloaded on const and non-const argument pointers. For
|
||||
example, in <cstring> strchr is overloaded. The functions isupper
|
||||
etc. in <cctype> typically implemented as macros in C are functions
|
||||
in C++, because they are overloaded with others of the same name
|
||||
defined in <locale>.
|
||||
|
||||
Many of the functions required in <cwctype> and <cwchar> cannot be
|
||||
implemented using underlying C facilities on intended targets because
|
||||
such facilities only partly exist.
|
||||
|
||||
Chapter 22 Locale
|
||||
------------------
|
||||
Headers: <locale>
|
||||
C headers: <clocale>
|
||||
|
||||
We have a "mostly complete" class locale, with the exception of
|
||||
code for constructing, and handling the names of, named locales.
|
||||
The ways that locales are named (particularly when categories
|
||||
(e.g. LC_TIME, LC_COLLATE) are different) varies among all target
|
||||
environments. This code must be written in various versions and
|
||||
chosen by configuration parameters.
|
||||
|
||||
Members of many of the facets defined in <locale> are stubs. Generally,
|
||||
there are two sets of facets: the base class facets (which are supposed
|
||||
to implement the "C" locale) and the "byname" facets, which are supposed
|
||||
to read files to determine their behavior. The base ctype<>, collate<>,
|
||||
and numpunct<> facets are "mostly complete", except that the table of
|
||||
bitmask values used for "is" operations, and corresponding mask values,
|
||||
are still defined in libio and just included/linked. (We will need to
|
||||
implement these tables independently, soon, but should take advantage
|
||||
of libio where possible.) The num_put<>::put members for integer types
|
||||
are "mostly complete".
|
||||
|
||||
A complete list of what has and has not been implemented may be
|
||||
found in CHECKLIST. However, note that the current definition of
|
||||
codecvt<wchar_t,char,mbstate_t> is wrong. It should simply write
|
||||
out the raw bytes representing the wide characters, rather than
|
||||
trying to convert each to a corresponding single "char" value.
|
||||
|
||||
Some of the facets are more important than others. Specifically,
|
||||
the members of ctype<>, numpunct<>, num_put<>, and num_get<> facets
|
||||
are used by other library facilities defined in <string>, <istream>,
|
||||
and <ostream>, and the codecvt<> facet is used by basic_filebuf<>
|
||||
in <fstream>, so a conforming iostream implementation depends on
|
||||
these.
|
||||
|
||||
The "long long" type eventually must be supported, but code mentioning
|
||||
it should be wrapped in #if guards to allow pedantic-mode compiling.
|
||||
|
||||
Performance of num_put<> and num_get<> depend critically on
|
||||
caching computed values in ios_base objects, and on extensions
|
||||
to the interface with streambufs.
|
||||
|
||||
Specifically: retrieving a copy of the locale object, extracting
|
||||
the needed facets, and gathering data from them, for each call to
|
||||
(e.g.) operator<< would be prohibitively slow. To cache format
|
||||
data for use by num_put<> and num_get<> we have a _Format_cache<>
|
||||
object stored in the ios_base::pword() array. This is constructed
|
||||
and initialized lazily, and is organized purely for utility. It
|
||||
is discarded when a new locale with different facets is imbued.
|
||||
|
||||
Using only the public interfaces of the iterator arguments to the
|
||||
facet functions would limit performance by forbidding "vector-style"
|
||||
character operations. The streambuf iterator optimizations are
|
||||
described under chapter 24, but facets can also bypass the streambuf
|
||||
iterators via explicit specializations and operate directly on the
|
||||
streambufs, and use extended interfaces to get direct access to the
|
||||
streambuf internal buffer arrays. These extensions are mentioned
|
||||
under chapter 27. These optimizations are particularly important
|
||||
for input parsing.
|
||||
|
||||
Unused virtual members of locale facets can be omitted, as mentioned
|
||||
above, by a smart linker.
|
||||
|
||||
Chapter 23 Containers
|
||||
----------------------
|
||||
Headers: <deque> <list> <queue> <stack> <vector> <map> <set> <bitset>
|
||||
|
||||
All the components in chapter 23 are implemented in the SGI STL.
|
||||
They are "mostly complete"; they include a large number of
|
||||
nonconforming extensions which must be wrapped. Some of these
|
||||
are used internally and must be renamed or duplicated.
|
||||
|
||||
The SGI components are optimized for large-memory environments. For
|
||||
embedded targets, different criteria might be more appropriate. Users
|
||||
will want to be able to tune this behavior. We should provide
|
||||
ways for users to compile the library with different memory usage
|
||||
characteristics.
|
||||
|
||||
A lot more work is needed on factoring out common code from different
|
||||
specializations to reduce code size here and in chapter 25. The
|
||||
easiest fix for this would be a compiler/ABI improvement that allows
|
||||
the compiler to recognize when a specialization depends only on the
|
||||
size (or other gross quality) of a template argument, and allow the
|
||||
linker to share the code with similar specializations. In its
|
||||
absence, many of the algorithms and containers can be partial-
|
||||
specialized, at least for the case of pointers, but this only solves
|
||||
a small part of the problem. Use of a type_traits-style template
|
||||
allows a few more optimization opportunities, more if the compiler
|
||||
can generate the specializations automatically.
|
||||
|
||||
As an optimization, containers can specialize on the default allocator
|
||||
and bypass it, or take advantage of details of its implementation
|
||||
after it has been improved upon.
|
||||
|
||||
Replacing the vector iterators, which currently are simple element
|
||||
pointers, with class objects would greatly increase the safety of the
|
||||
client interface, and also permit a "debug" mode in which range,
|
||||
ownership, and validity are rigorously checked. The current use of
|
||||
pointers for iterators is evil.
|
||||
|
||||
As mentioned for chapter 24, the deque iterator is a good example of
|
||||
an opportunity to implement a "staged" iterator that would benefit
|
||||
from specializations of some algorithms.
|
||||
|
||||
Chapter 24 Iterators
|
||||
---------------------
|
||||
Headers: <iterator>
|
||||
|
||||
Standard iterators are "mostly complete", with the exception of
|
||||
the stream iterators, which are not yet templatized on the
|
||||
stream type. Also, the base class template iterator<> appears
|
||||
to be wrong, so everything derived from it must also be wrong,
|
||||
currently.
|
||||
|
||||
The streambuf iterators (currently located in stl/bits/std_iterator.h,
|
||||
but should be under bits/) can be rewritten to take advantage of
|
||||
friendship with the streambuf implementation.
|
||||
|
||||
Matt Austern has identified opportunities where certain iterator
|
||||
types, particularly including streambuf iterators and deque
|
||||
iterators, have a "two-stage" quality, such that an intermediate
|
||||
limit can be checked much more quickly than the true limit on
|
||||
range operations. If identified with a member of iterator_traits,
|
||||
algorithms may be specialized for this case. Of course the
|
||||
iterators that have this quality can be identified by specializing
|
||||
a traits class.
|
||||
|
||||
Many of the algorithms must be specialized for the streambuf
|
||||
iterators, to take advantage of block-mode operations, in order
|
||||
to allow iostream/locale operations' performance not to suffer.
|
||||
It may be that they could be treated as staged iterators and
|
||||
take advantage of those optimizations.
|
||||
|
||||
Chapter 25 Algorithms
|
||||
----------------------
|
||||
Headers: <algorithm>
|
||||
C headers: <cstdlib> (also in 18, 21, 26))
|
||||
|
||||
The algorithms are "mostly complete". As mentioned above, they
|
||||
are optimized for speed at the expense of code and data size.
|
||||
|
||||
Specializations of many of the algorithms for non-STL types would
|
||||
give performance improvements, but we must use great care not to
|
||||
interfere with fragile template overloading semantics for the
|
||||
standard interfaces. Conventionally the standard function template
|
||||
interface is an inline which delegates to a non-standard function
|
||||
which is then overloaded (this is already done in many places in
|
||||
the library). Particularly appealing opportunities for the sake of
|
||||
iostream performance are for copy and find applied to streambuf
|
||||
iterators or (as noted elsewhere) for staged iterators, of which
|
||||
the streambuf iterators are a good example.
|
||||
|
||||
The bsearch and qsort functions cannot be overloaded properly as
|
||||
required by the standard because gcc does not yet allow overloading
|
||||
on the extern-"C"-ness of a function pointer.
|
||||
|
||||
Chapter 26 Numerics
|
||||
--------------------
|
||||
Headers: <complex> <valarray> <numeric>
|
||||
C headers: <cmath>, <cstdlib> (also 18, 21, 25)
|
||||
|
||||
Numeric components: Gabriel dos Reis's valarray, Drepper's complex,
|
||||
and the few algorithms from the STL are "mostly done". Of course
|
||||
optimization opportunities abound for the numerically literate. It
|
||||
is not clear whether the valarray implementation really conforms
|
||||
fully, in the assumptions it makes about aliasing (and lack thereof)
|
||||
in its arguments.
|
||||
|
||||
The C div() and ldiv() functions are interesting, because they are the
|
||||
only case where a C library function returns a class object by value.
|
||||
Since the C++ type div_t must be different from the underlying C type
|
||||
(which is in the wrong namespace) the underlying functions div() and
|
||||
ldiv() cannot be re-used efficiently. Fortunately they are trivial to
|
||||
re-implement.
|
||||
|
||||
Chapter 27 Iostreams
|
||||
---------------------
|
||||
Headers: <iosfwd> <streambuf> <ios> <ostream> <istream> <iostream>
|
||||
<iomanip> <sstream> <fstream>
|
||||
C headers: <cstdio> <cwchar> (also in 21)
|
||||
|
||||
Iostream is currently in a very incomplete state. <iosfwd>, <iomanip>,
|
||||
ios_base, and basic_ios<> are "mostly complete". basic_streambuf<> and
|
||||
basic_ostream<> are well along, but basic_istream<> has had little work
|
||||
done. The standard stream objects, <sstream> and <fstream> have been
|
||||
started; basic_filebuf<> "write" functions have been implemented just
|
||||
enough to do "hello, world".
|
||||
|
||||
Most of the istream and ostream operators << and >> (with the exception
|
||||
of the op<<(integer) ones) have not been changed to use locale primitives,
|
||||
sentry objects, or char_traits members.
|
||||
|
||||
All these templates should be manually instantiated for char and
|
||||
wchar_t in a way that links only used members into user programs.
|
||||
|
||||
Streambuf is fertile ground for optimization extensions. An extended
|
||||
interface giving iterator access to its internal buffer would be very
|
||||
useful for other library components.
|
||||
|
||||
Iostream operations (primarily operators << and >>) can take advantage
|
||||
of the case where user code has not specified a locale, and bypass locale
|
||||
operations entirely. The current implementation of op<</num_put<>::put,
|
||||
for the integer types, demonstrates how they can cache encoding details
|
||||
from the locale on each operation. There is lots more room for
|
||||
optimization in this area.
|
||||
|
||||
The definition of the relationship between the standard streams
|
||||
cout et al. and stdout et al. requires something like a "stdiobuf".
|
||||
The SGI solution of using double-indirection to actually use a
|
||||
stdio FILE object for buffering is unsatisfactory, because it
|
||||
interferes with peephole loop optimizations.
|
||||
|
||||
The <sstream> header work has begun. stringbuf can benefit from
|
||||
friendship with basic_string<> and basic_string<>::_Rep to use
|
||||
those objects directly as buffers, and avoid allocating and making
|
||||
copies.
|
||||
|
||||
The basic_filebuf<> template is a complex beast. It is specified to
|
||||
use the locale facet codecvt<> to translate characters between native
|
||||
files and the locale character encoding. In general this involves
|
||||
two buffers, one of "char" representing the file and another of
|
||||
"char_type", for the stream, with codecvt<> translating. The process
|
||||
is complicated by the variable-length nature of the translation, and
|
||||
the need to seek to corresponding places in the two representations.
|
||||
For the case of basic_filebuf<char>, when no translation is needed,
|
||||
a single buffer suffices. A specialized filebuf can be used to reduce
|
||||
code space overhead when no locale has been imbued. Matt Austern's
|
||||
work at SGI will be useful, perhaps directly as a source of code, or
|
||||
at least as an example to draw on.
|
||||
|
||||
Filebuf, almost uniquely (cf. operator new), depends heavily on
|
||||
underlying environmental facilities. In current releases iostream
|
||||
depends fairly heavily on libio constant definitions, but it should
|
||||
be made independent. It also depends on operating system primitives
|
||||
for file operations. There is immense room for optimizations using
|
||||
(e.g.) mmap for reading. The shadow/ directory wraps, besides the
|
||||
standard C headers, the libio.h and unistd.h headers, for use mainly
|
||||
by filebuf. These wrappings have not been completed, though there
|
||||
is scaffolding in place.
|
||||
|
||||
The encapulation of certain C header <cstdio> names presents an
|
||||
interesting problem. It is possible to define an inline std::fprintf()
|
||||
implemented in terms of the 'extern "C"' vfprintf(), but there is no
|
||||
standard vfscanf() to use to implement std::fscanf(). It appears that
|
||||
vfscanf but be re-implemented in C++ for targets where no vfscanf
|
||||
extension has been defined. This is interesting in that it seems
|
||||
to be the only significant case in the C library where this kind of
|
||||
rewriting is necessary. (Of course Glibc provides the vfscanf()
|
||||
extension.) (The functions related to exit() must be rewritten
|
||||
for other reasons.)
|
||||
|
||||
|
||||
Annex D
|
||||
-------
|
||||
Headers: <strstream>
|
||||
|
||||
Annex D defines many non-library features, and many minor
|
||||
modifications to various headers, and a complete header.
|
||||
It is "mostly done", except that the libstdc++-2 <strstream>
|
||||
header has not been adopted into the library, or checked to
|
||||
verify that it matches the draft in those details that were
|
||||
clarified by the committee. Certainly it must at least be
|
||||
moved into the std namespace.
|
||||
|
||||
We still need to wrap all the deprecated features in #if guards
|
||||
so that pedantic compile modes can detect their use.
|
||||
|
||||
Nonstandard Extensions
|
||||
----------------------
|
||||
Headers: <iostream.h> <strstream.h> <hash> <rbtree>
|
||||
<pthread_alloc> <stdiobuf> (etc.)
|
||||
|
||||
User code has come to depend on a variety of nonstandard components
|
||||
that we must not omit. Much of this code can be adopted from
|
||||
libstdc++-v2 or from the SGI STL. This particularly includes
|
||||
<iostream.h>, <strstream.h>, and various SGI extensions such
|
||||
as <hash_map.h>. Many of these are already placed in the
|
||||
subdirectories ext/ and backward/. (Note that it is better to
|
||||
include them via "<backward/hash_map.h>" or "<ext/hash_map>" than
|
||||
to search the subdirectory itself via a "-I" directive.
|
||||
|
|
@ -1,164 +0,0 @@
|
|||
std::allocator
|
||||
|
||||
- persistent allocator
|
||||
|
||||
- shared memory allocator (use or link to boost::shmem::allocator)
|
||||
|
||||
std::string
|
||||
|
||||
- document __gnu_cxx::__versa_string, add new policies
|
||||
(Policy-based design incorporating COW
|
||||
vs. deep copy issues, MT scalability
|
||||
See Andrei Alexandrescu, June 2001, C/C++ Users Journal
|
||||
"Generic<Programming>: A Policy-Based basic_string Implementation"
|
||||
http://www.cuj.com/documents/s=7994/cujcexp1906alexandr/)
|
||||
|
||||
- operator!= and utility/rel_ops operators need to be made safe with
|
||||
string and vector iterator classes. basic_string::reverse_iterator may
|
||||
be implemented incorrectly, or need things like
|
||||
operator==(__normal_iterator, const char*&), and swap(vector)
|
||||
|
||||
- 'do the right thing' ctor fixing needs to be done for string. This
|
||||
is still subject to some debate on the library issues list, so I
|
||||
suggest punting till the dust clears.
|
||||
|
||||
- fix template members of basic_string<> to overload iterators and
|
||||
non-iterators properly. (This is the infamous hack as in vector<> etc
|
||||
23.1.1 para 10.)
|
||||
|
||||
std::locale
|
||||
|
||||
- implement __convert_to_v and __convert_from_v without "C" library
|
||||
functions and and LANG environment variable dependencies.
|
||||
|
||||
- use localedata to implement generic named (non-MT-safe) locales?
|
||||
Figure out a way to use ICU data, like libjava? Re-package and use
|
||||
the glibc localedata, even if we aren't on linux? Need a generic
|
||||
locale model that does something besides the "C" locale.
|
||||
|
||||
- make locale::classic() separate from named locale code. This will
|
||||
improve the static linkage situation, but will require new
|
||||
initialization code. In particular, we need lazy-initialization of
|
||||
locale::classic(), and maybe the has_facet/use_facet functions for all
|
||||
the required facets. The end goal is a self-contained
|
||||
locale_init.cc, or one with transitive closure without the locale
|
||||
instantiations (locale-inst.cc) or the named locale bits
|
||||
(localename.cc).
|
||||
|
||||
- Jerry(?)/Paolo(?) work on __float_to_char.
|
||||
|
||||
- minimize ctype convertion in data facets, see numpunct/num_put/num_get
|
||||
|
||||
std::basic_filebuf, 27_io
|
||||
|
||||
- wfilebuf, get variable-encoding working and tested, including
|
||||
positioning and seeking. (I think this may be done now)
|
||||
|
||||
- wfilebuf testsuite (getting there...)
|
||||
|
||||
- look ahead for unbuffered io, so know when multiple putc's can be
|
||||
coalesced.
|
||||
|
||||
- unlocked __basic_file + new mutext class
|
||||
|
||||
- optimized the sentries for istream/ostream
|
||||
|
||||
- v2 vs. v3 speed
|
||||
|
||||
- add optimization hooks (esp. whitespace eating) to streambuf
|
||||
- add _M_begin() and _M_end() to streambuf
|
||||
- add algorithm specializations for [io]streambuf_iterator (copy find etc.)
|
||||
|
||||
testsuite
|
||||
|
||||
- valgrind hooks into make check so can tell memory leakage
|
||||
Some commentary on the valgrind users list
|
||||
|
||||
- add hooks for qmtest, pychart, other for visual diffs
|
||||
|
||||
- automatic testing of interactive tests
|
||||
|
||||
- diffing generated output files
|
||||
|
||||
- provide testsuites for numerics.
|
||||
|
||||
- make check-abi needs to have full symbol checking. Scope the LSB
|
||||
testsuite, see what's going on with the typeinfo etc. bits.
|
||||
|
||||
- try to do a better job of ABI testing, with instantiations of all
|
||||
standard-specified types checked, not just exported symbols.
|
||||
|
||||
g++/binutils
|
||||
|
||||
- compression for wide versions of basic types, not just narrow
|
||||
|
||||
threads
|
||||
|
||||
- create MT abstraction layer for atomicity to pthreads.
|
||||
|
||||
- solution for threads + C++.
|
||||
|
||||
other/random
|
||||
|
||||
- relocations, work on getting these down
|
||||
|
||||
- issues with __builtin_memcpy and std::copy from Jerry Quinn
|
||||
http://gcc.gnu.org/ml/libstdc++/2003-02/msg00056.html
|
||||
http://gcc.gnu.org/ml/libstdc++/2003-02/msg00302.html
|
||||
http://gcc.gnu.org/ml/gcc/2003-10/msg01305.html
|
||||
|
||||
- fix dependency tracking for includes (.h, .tcc) during build process.
|
||||
|
||||
- coordinate with "C" library people the "C" compatibility headers.
|
||||
|
||||
- Think about naming all member data and member functions consistently
|
||||
as per
|
||||
funtions: _M_verb_adverb
|
||||
data: _M_noun_adjective
|
||||
|
||||
- A C++STYLE guide that deals with nested namespaces, and that
|
||||
everybody can live with.
|
||||
|
||||
- exception specifications need to be reviewed for all parts of the
|
||||
library support and utility areas, particularly <new>. Part of this is
|
||||
a standards issue, where the 27_io standard is really in an odd
|
||||
spot. Do the work to make this consistent.
|
||||
|
||||
- C-related issues WRT to io and filepos, mbstate_t. Seeking in wide
|
||||
streams. May need to define operators for mbstate_t so that
|
||||
'mbstate_t& == mbstate_t' is something that can be done.
|
||||
|
||||
- scoping/linking issues WRT to C structs need to be worked out. See
|
||||
Nathan's commentary on cantrip, http://www.cantrip.org/cheaders.html
|
||||
|
||||
- auto_ptr: seems to be some disagreement on what is
|
||||
standards-conformant behavior, specially on conversion operators.
|
||||
|
||||
- list::assignment operator needs const_cast
|
||||
|
||||
- a cleaner division between pointers-to-value_type and true iterators
|
||||
needs to be drawn throughout the entire STL implementation.
|
||||
|
||||
- priority_queue conversions may be non-conformant
|
||||
|
||||
- Protect valarray::result_type (not Standard) and make it work with
|
||||
the various helper classes.
|
||||
|
||||
- Make sure `valarray<bool> & == _Expr<_BinClos<logical_or,_ValArray,_ValArray,double,double>,bool>'
|
||||
is defined
|
||||
|
||||
- All of the Library working group closed issues need to be
|
||||
addressed. Some of them proposed resolutions are already in the v-3
|
||||
sources, with macro-guards. Also, same with the TR.
|
||||
|
||||
- need to think about doing a .texi or DocBook manual, instead of all
|
||||
these HTML pages. In addition, it would be nice to have a full manual,
|
||||
instead of a lot of ad-hoc pages. Weaknesses include numerics, locale,
|
||||
and io.
|
||||
|
||||
- add FAQ entries -- improve the install instructions
|
||||
|
||||
- add HOWTO entries
|
||||
|
||||
- do more doxygen manpages
|
||||
|
|
@ -1,991 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta name="AUTHOR" content="bkoz@gcc.gnu.org (Benjamin Kosnik)" />
|
||||
<meta name="KEYWORDS" content="C++, libstdc++, dynamic, shared, library, ABI, version" />
|
||||
<meta name="DESCRIPTION" content="C++ Standard Library ABI" />
|
||||
<meta name="GENERATOR" content="emacs and ten fingers" />
|
||||
<title>Standard C++ Library ABI</title>
|
||||
<link rel="StyleSheet" href="lib3styles.css" type="text/css" />
|
||||
<link rel="Start" href="documentation.html" type="text/html"
|
||||
title="GNU C++ Standard Library" />
|
||||
<link rel="Copyright" href="17_intro/license.html" type="text/html" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 class="centered"><a name="top">C++ Standard Library ABI</a></h1>
|
||||
|
||||
<p class="fineprint"><em>
|
||||
The latest version of this document is always available at
|
||||
<a href="http://gcc.gnu.org/onlinedocs/libstdc++/abi.html">
|
||||
http://gcc.gnu.org/onlinedocs/libstdc++/abi.html</a>.
|
||||
</em></p>
|
||||
|
||||
<p><em>
|
||||
To the <a href="http://gcc.gnu.org/libstdc++/">libstdc++ homepage</a>.
|
||||
</em></p>
|
||||
|
||||
<!-- ####################################################### -->
|
||||
<hr />
|
||||
<h3 class="left">
|
||||
<a name="CXXinterface">The C++ interface</a>
|
||||
</h3>
|
||||
|
||||
<p> C++ applications often dependent on specific language support
|
||||
routines, say for throwing exceptions, or catching exceptions, and
|
||||
perhaps also dependent on features in the C++ Standard Library.
|
||||
</p>
|
||||
|
||||
<p> The C++ Standard Library has many include files, types defined in
|
||||
those include files, specific named functions, and other behavior. The
|
||||
text of these behaviors, as written in source include files, is called
|
||||
the Application Programing Interface, or API.
|
||||
</p>
|
||||
|
||||
<p> Furthermore, C++ source that is compiled into object files is
|
||||
transformed by the compiler: it arranges objects with specific
|
||||
alignment and in a particular layout, mangling names according to a
|
||||
well-defined algorithm, has specific arrangements for the support of
|
||||
virtual functions, etc. These details are defined as the compiler
|
||||
Application Binary Interface, or ABI. The GNU C++ compiler uses an
|
||||
industry-standard C++ ABI starting with version 3. Details can be
|
||||
found in the <a href="http://www.codesourcery.com/cxx-abi/abi.html">
|
||||
ABI specification</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The GNU C++ compiler, g++, has a compiler command line option to
|
||||
switch between various different C++ ABIs. This explicit version
|
||||
switch is the flag <code> -fabi-version</code>. In addition, some
|
||||
g++ command line options may change the ABI as a side-effect of
|
||||
use. Such flags include <code>-fpack-struct</code> and
|
||||
<code>-fno-exceptions</code>, but include others: see the complete
|
||||
list in the GCC manual under the heading <a
|
||||
href="http://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code%20Gen%20Options">Options
|
||||
for Code Generation Conventions</a>.
|
||||
</p>
|
||||
|
||||
<p> The configure options used when building a specific libstdc++
|
||||
version may also impact the resulting library ABI. The available
|
||||
configure options, and their impact on the library ABI, are documented
|
||||
<a href="http://gcc.gnu.org/onlinedocs/libstdc++/configopts.html">
|
||||
here</a>.
|
||||
</p>
|
||||
|
||||
<p> Putting all of these ideas together results in the C++ Standard
|
||||
library ABI, which is the compilation of a given library API by a
|
||||
given compiler ABI. In a nutshell:
|
||||
</p>
|
||||
|
||||
<code> library API + compiler ABI = library ABI</code>
|
||||
|
||||
<p>
|
||||
The library ABI is mostly of interest for end-users who have
|
||||
unresolved symbols and are linking dynamically to the C++ Standard
|
||||
library, and who thus must be careful to compile their application
|
||||
with a compiler that is compatible with the available C++ Standard
|
||||
library binary. In this case, compatible is defined with the equation
|
||||
above: given an application compiled with a given compiler ABI and
|
||||
library API, it will work correctly with a Standard C++ Library
|
||||
created with the same constraints.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To use a specific version of the C++ ABI, one must use a
|
||||
corresponding GNU C++ toolchain (Ie, g++ and libstdc++) that
|
||||
implements the C++ ABI in question.
|
||||
</p>
|
||||
|
||||
<h3 class="left">
|
||||
<a name="ABI_versioning">Versioning</a>
|
||||
</h3>
|
||||
|
||||
<p> The C++ interface has evolved throughout the history of the GNU
|
||||
C++ toolchain. With each release, various details have been changed so
|
||||
as to give distinct versions to the C++ interface.
|
||||
</p>
|
||||
|
||||
<h5 class="left">
|
||||
<a name="goals">Goals of versioning</a>
|
||||
</h5>
|
||||
|
||||
<p>Extending existing, stable ABIs. Versioning gives subsequent stable
|
||||
releases series libraries the ability to add new symbols and add
|
||||
functionality, all the while retaining backwards compatibility with
|
||||
the previous releases in the series. Note: the reverse is not true. It
|
||||
is not possible to take binaries linked with the latest version of a
|
||||
release series (if symbols have been added) and expect the initial
|
||||
release of the series to remain link compatible.
|
||||
</p>
|
||||
|
||||
<p>Allows multiple, incompatible ABIs to coexist at the same time.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
</p>
|
||||
|
||||
<h5 class="left">
|
||||
<a name="details"> Version History </a>
|
||||
</h5>
|
||||
<p>
|
||||
How can this complexity be managed? What does C++ versioning mean?
|
||||
Because library and compiler changes often make binaries compiled
|
||||
with one version of the GNU tools incompatible with binaries
|
||||
compiled with other (either newer or older) versions of the same GNU
|
||||
tools, specific techniques are used to make managing this complexity
|
||||
easier.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The following techniques are used:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li> <p>Release versioning on the libgcc_s.so binary. This is
|
||||
implemented via file names and the ELF DT_SONAME mechanism (at least
|
||||
on ELF systems).</p>
|
||||
|
||||
<p>It is versioned as follows:
|
||||
</p>
|
||||
<ul>
|
||||
<li>gcc-3.0.0: libgcc_s.so.1</li>
|
||||
<li>gcc-3.0.1: libgcc_s.so.1</li>
|
||||
<li>gcc-3.0.2: libgcc_s.so.1</li>
|
||||
<li>gcc-3.0.3: libgcc_s.so.1</li>
|
||||
<li>gcc-3.0.4: libgcc_s.so.1</li>
|
||||
<li>gcc-3.1.0: libgcc_s.so.1</li>
|
||||
<li>gcc-3.1.1: libgcc_s.so.1</li>
|
||||
<li>gcc-3.2.0: libgcc_s.so.1</li>
|
||||
<li>gcc-3.2.1: libgcc_s.so.1</li>
|
||||
<li>gcc-3.2.2: libgcc_s.so.1</li>
|
||||
<li>gcc-3.2.3: libgcc_s.so.1</li>
|
||||
<li>gcc-3.3.0: libgcc_s.so.1</li>
|
||||
<li>gcc-3.3.1: libgcc_s.so.1</li>
|
||||
<li>gcc-3.3.2: libgcc_s.so.1</li>
|
||||
<li>gcc-3.3.3: libgcc_s.so.1</li>
|
||||
<li>gcc-3.4.x, gcc-4.0.x, gcc-4.1.x, gcc-4.2.x: on m68k-linux and
|
||||
hppa-linux this is either libgcc_s.so.1 (when configuring
|
||||
<code>--with-sjlj-exceptions</code>) or libgcc_s.so.2. For all
|
||||
others, this is libgcc_s.so.1. </li> </ul>
|
||||
<p></p>
|
||||
</li>
|
||||
|
||||
<li>Symbol versioning on the libgcc_s.so binary.
|
||||
<p>mapfile: gcc/libgcc-std.ver</p>
|
||||
|
||||
<p>It is versioned with the following labels and version
|
||||
definitions, where the version definition is the maximum for a
|
||||
particular release. Labels are cumulative. If a particular release
|
||||
is not listed, it has the same version labels as the preceeding
|
||||
release.</p>
|
||||
<ul>
|
||||
<li>gcc-3.0.0: GCC_3.0</li>
|
||||
<li>gcc-3.3.0: GCC_3.3</li>
|
||||
<li>gcc-3.3.1: GCC_3.3.1</li>
|
||||
<li>gcc-3.3.2: GCC_3.3.2</li>
|
||||
<li>gcc-3.3.4: GCC_3.3.4</li>
|
||||
<li>gcc-3.4.0: GCC_3.4</li>
|
||||
<li>gcc-3.4.2: GCC_3.4.2</li>
|
||||
<li>gcc-3.4.4: GCC_3.4.4</li>
|
||||
<li>gcc-4.0.0: GCC_4.0.0</li>
|
||||
<li>gcc-4.1.0: GCC_4.1.0</li>
|
||||
<li>gcc-4.2.0: GCC_4.2.0</li>
|
||||
</ul>
|
||||
<p></p>
|
||||
</li>
|
||||
|
||||
<li>Release versioning on the libstdc++.so binary, implemented in the same was as the libgcc_s.so binary, above.
|
||||
|
||||
<p>It is versioned as follows:
|
||||
</p>
|
||||
<ul>
|
||||
<li>gcc-3.0.0: libstdc++.so.3.0.0</li>
|
||||
<li>gcc-3.0.1: libstdc++.so.3.0.1</li>
|
||||
<li>gcc-3.0.2: libstdc++.so.3.0.2</li>
|
||||
<li>gcc-3.0.3: libstdc++.so.3.0.2 (Error should be libstdc++.so.3.0.3)</li>
|
||||
<li>gcc-3.0.4: libstdc++.so.3.0.4</li>
|
||||
<li>gcc-3.1.0: libstdc++.so.4.0.0</li>
|
||||
<li>gcc-3.1.1: libstdc++.so.4.0.1</li>
|
||||
<li>gcc-3.2.0: libstdc++.so.5.0.0</li>
|
||||
<li>gcc-3.2.1: libstdc++.so.5.0.1</li>
|
||||
<li>gcc-3.2.2: libstdc++.so.5.0.2</li>
|
||||
<li>gcc-3.2.3: libstdc++.so.5.0.3 (Not strictly required)</li>
|
||||
<li>gcc-3.3.0: libstdc++.so.5.0.4</li>
|
||||
<li>gcc-3.3.1: libstdc++.so.5.0.5</li>
|
||||
<li>gcc-3.3.2: libstdc++.so.5.0.5</li>
|
||||
<li>gcc-3.3.3: libstdc++.so.5.0.5</li>
|
||||
<li>gcc-3.4.0: libstdc++.so.6.0.0</li>
|
||||
<li>gcc-3.4.1: libstdc++.so.6.0.1</li>
|
||||
<li>gcc-3.4.2: libstdc++.so.6.0.2</li>
|
||||
<li>gcc-3.4.3: libstdc++.so.6.0.3</li>
|
||||
<li>gcc-3.4.4: libstdc++.so.6.0.3</li>
|
||||
<li>gcc-3.4.5: libstdc++.so.6.0.3</li>
|
||||
<li>gcc-3.4.6: libstdc++.so.6.0.3</li>
|
||||
<li>gcc-4.0.0: libstdc++.so.6.0.4</li>
|
||||
<li>gcc-4.0.1: libstdc++.so.6.0.5</li>
|
||||
<li>gcc-4.0.2: libstdc++.so.6.0.6</li>
|
||||
<li>gcc-4.0.3: libstdc++.so.6.0.7</li>
|
||||
<li>gcc-4.1.0: libstdc++.so.6.0.7</li>
|
||||
<li>gcc-4.1.1: libstdc++.so.6.0.8</li>
|
||||
<li>gcc-4.1.2: libstdc++.so.6.0.8</li>
|
||||
<li>gcc-4.2.0: libstdc++.so.6.0.9</li>
|
||||
</ul>
|
||||
<p></p>
|
||||
</li>
|
||||
|
||||
<li>Symbol versioning on the libstdc++.so binary.
|
||||
|
||||
<p>mapfile: libstdc++/config/linker-map.gnu</p>
|
||||
<p>It is versioned with the following labels and version
|
||||
definitions, where the version definition is the maximum for a
|
||||
particular release. Note, only symbol which are newly introduced
|
||||
will use the maximum version definition. Thus, for release series
|
||||
with the same label, but incremented version definitions, the later
|
||||
release has both versions. (An example of this would be the
|
||||
gcc-3.2.1 release, which has GLIBCPP_3.2.1 for new symbols and
|
||||
GLIBCPP_3.2 for symbols that were introduced in the gcc-3.2.0
|
||||
release.) If a particular release is not listed, it has the same
|
||||
version labels as the preceeding release.
|
||||
</p>
|
||||
<ul>
|
||||
<li>gcc-3.0.0: (Error, not versioned)</li>
|
||||
<li>gcc-3.0.1: (Error, not versioned)</li>
|
||||
<li>gcc-3.0.2: (Error, not versioned)</li>
|
||||
<li>gcc-3.0.3: (Error, not versioned)</li>
|
||||
<li>gcc-3.0.4: (Error, not versioned)</li>
|
||||
<li>gcc-3.1.0: GLIBCPP_3.1, CXXABI_1</li>
|
||||
<li>gcc-3.1.1: GLIBCPP_3.1, CXXABI_1</li>
|
||||
<li>gcc-3.2.0: GLIBCPP_3.2, CXXABI_1.2</li>
|
||||
<li>gcc-3.2.1: GLIBCPP_3.2.1, CXXABI_1.2</li>
|
||||
<li>gcc-3.2.2: GLIBCPP_3.2.2, CXXABI_1.2</li>
|
||||
<li>gcc-3.2.3: GLIBCPP_3.2.2, CXXABI_1.2</li>
|
||||
<li>gcc-3.3.0: GLIBCPP_3.2.2, CXXABI_1.2.1</li>
|
||||
<li>gcc-3.3.1: GLIBCPP_3.2.3, CXXABI_1.2.1</li>
|
||||
<li>gcc-3.3.2: GLIBCPP_3.2.3, CXXABI_1.2.1</li>
|
||||
<li>gcc-3.3.3: GLIBCPP_3.2.3, CXXABI_1.2.1</li>
|
||||
<li>gcc-3.4.0: GLIBCXX_3.4, CXXABI_1.3</li>
|
||||
<li>gcc-3.4.1: GLIBCXX_3.4.1, CXXABI_1.3</li>
|
||||
<li>gcc-3.4.2: GLIBCXX_3.4.2</li>
|
||||
<li>gcc-3.4.3: GLIBCXX_3.4.3</li>
|
||||
<li>gcc-4.0.0: GLIBCXX_3.4.4, CXXABI_1.3.1</li>
|
||||
<li>gcc-4.0.1: GLIBCXX_3.4.5</li>
|
||||
<li>gcc-4.0.2: GLIBCXX_3.4.6</li>
|
||||
<li>gcc-4.0.3: GLIBCXX_3.4.7</li>
|
||||
<li>gcc-4.1.1: GLIBCXX_3.4.8</li>
|
||||
<li>gcc-4.2.0: GLIBCXX_3.4.9</li>
|
||||
</ul>
|
||||
<p></p>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<p>Incremental bumping of a compiler pre-defined macro,
|
||||
__GXX_ABI_VERSION. This macro is defined as the version of the
|
||||
compiler v3 ABI, with g++ 3.0.x being version 100. This macro will
|
||||
be automatically defined whenever g++ is used (the curious can
|
||||
test this by invoking g++ with the '-v' flag.)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This macro was defined in the file "lang-specs.h" in the gcc/cp directory.
|
||||
Later versions defined it in "c-common.c" in the gcc directory, and from
|
||||
G++ 3.4 it is defined in c-cppbuiltin.c and its value determined by the
|
||||
'-fabi-version' command line option.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
It is versioned as follows, where 'n' is given by '-fabi-version=n':
|
||||
</p>
|
||||
<ul>
|
||||
<li>gcc-3.0.x: 100</li>
|
||||
<li>gcc-3.1.x: 100 (Error, should be 101)</li>
|
||||
<li>gcc-3.2.x: 102</li>
|
||||
<li>gcc-3.3.x: 102</li>
|
||||
<li>gcc-3.4.x, gcc-4.0.x, gcc-4.1.x, gcc-4.2.x: 102 (when n=1)</li>
|
||||
<li>gcc-3.4.x, gcc-4.0.x, gcc-4.1.x, gcc-4.2.x: 1000 + n (when n>1)</li>
|
||||
<li>gcc-3.4.x, gcc-4.0.x, gcc-4.1.x, gcc-4.2.x: 999999 (when n=0)</li>
|
||||
</ul>
|
||||
<p></p>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<p>Changes to the default compiler option for
|
||||
<code>-fabi-version</code>.
|
||||
</p>
|
||||
<p>
|
||||
It is versioned as follows:
|
||||
</p>
|
||||
<ul>
|
||||
<li>gcc-3.0.x: (Error, not versioned) </li>
|
||||
<li>gcc-3.1.x: (Error, not versioned) </li>
|
||||
<li>gcc-3.2.x: <code>-fabi-version=1</code></li>
|
||||
<li>gcc-3.3.x: <code>-fabi-version=1</code></li>
|
||||
<li>gcc-3.4.x, gcc-4.0.x, gcc-4.1.x, gcc-4.2.x: <code>-fabi-version=2</code></li>
|
||||
</ul>
|
||||
<p></p>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<p>Incremental bumping of a library pre-defined macro. For releases
|
||||
before 3.4.0, the macro is __GLIBCPP__. For later releases, it's
|
||||
__GLIBCXX__. (The libstdc++ project generously changed from CPP to
|
||||
CXX throughout its source to allow the "C" pre-processor the CPP
|
||||
macro namespace.) These macros are defined as the date the library
|
||||
was released, in compressed ISO date format, as an unsigned long.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This macro is defined in the file "c++config" in the
|
||||
"libstdc++/include/bits" directory. (Up to gcc-4.1.0, it was
|
||||
changed every night by an automated script. Since gcc-4.1.0, it is
|
||||
the same value as gcc/DATESTAMP.)
|
||||
</p>
|
||||
<p>
|
||||
It is versioned as follows:
|
||||
</p>
|
||||
<ul>
|
||||
<li>gcc-3.0.0: 20010615</li>
|
||||
<li>gcc-3.0.1: 20010819</li>
|
||||
<li>gcc-3.0.2: 20011023</li>
|
||||
<li>gcc-3.0.3: 20011220</li>
|
||||
<li>gcc-3.0.4: 20020220</li>
|
||||
<li>gcc-3.1.0: 20020514</li>
|
||||
<li>gcc-3.1.1: 20020725</li>
|
||||
<li>gcc-3.2.0: 20020814</li>
|
||||
<li>gcc-3.2.1: 20021119</li>
|
||||
<li>gcc-3.2.2: 20030205</li>
|
||||
<li>gcc-3.2.3: 20030422</li>
|
||||
<li>gcc-3.3.0: 20030513</li>
|
||||
<li>gcc-3.3.1: 20030804</li>
|
||||
<li>gcc-3.3.2: 20031016</li>
|
||||
<li>gcc-3.3.3: 20040214</li>
|
||||
<li>gcc-3.4.0: 20040419</li>
|
||||
<li>gcc-3.4.1: 20040701</li>
|
||||
<li>gcc-3.4.2: 20040906</li>
|
||||
<li>gcc-3.4.3: 20041105</li>
|
||||
<li>gcc-3.4.4: 20050519</li>
|
||||
<li>gcc-3.4.5: 20051201</li>
|
||||
<li>gcc-3.4.6: 20060306</li>
|
||||
<li>gcc-4.0.0: 20050421</li>
|
||||
<li>gcc-4.0.1: 20050707</li>
|
||||
<li>gcc-4.0.2: 20050921</li>
|
||||
<li>gcc-4.0.3: 20060309</li>
|
||||
<li>gcc-4.1.0: 20060228</li>
|
||||
<li>gcc-4.1.1: 20060524</li>
|
||||
<li>gcc-4.1.2: 20070214</li>
|
||||
<li>gcc-4.2.0: 20070514</li>
|
||||
</ul>
|
||||
<p></p>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<p>
|
||||
Incremental bumping of a library pre-defined macro,
|
||||
_GLIBCPP_VERSION. This macro is defined as the released version of
|
||||
the library, as a string literal. This is only implemented in
|
||||
gcc-3.1.0 releases and higher, and is deprecated in 3.4 (where it
|
||||
is called _GLIBCXX_VERSION).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This macro is defined in the file "c++config" in the
|
||||
"libstdc++/include/bits" directory and is generated
|
||||
automatically by autoconf as part of the configure-time generation
|
||||
of config.h.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
It is versioned as follows:
|
||||
</p>
|
||||
<ul>
|
||||
<li>gcc-3.0.0: "3.0.0"</li>
|
||||
<li>gcc-3.0.1: "3.0.0" (Error, should be "3.0.1")</li>
|
||||
<li>gcc-3.0.2: "3.0.0" (Error, should be "3.0.2")</li>
|
||||
<li>gcc-3.0.3: "3.0.0" (Error, should be "3.0.3")</li>
|
||||
<li>gcc-3.0.4: "3.0.0" (Error, should be "3.0.4")</li>
|
||||
<li>gcc-3.1.0: "3.1.0"</li>
|
||||
<li>gcc-3.1.1: "3.1.1"</li>
|
||||
<li>gcc-3.2.0: "3.2"</li>
|
||||
<li>gcc-3.2.1: "3.2.1"</li>
|
||||
<li>gcc-3.2.2: "3.2.2"</li>
|
||||
<li>gcc-3.2.3: "3.2.3"</li>
|
||||
<li>gcc-3.3.0: "3.3"</li>
|
||||
<li>gcc-3.3.1: "3.3.1"</li>
|
||||
<li>gcc-3.3.2: "3.3.2"</li>
|
||||
<li>gcc-3.3.3: "3.3.3"</li>
|
||||
<li>gcc-3.4.x: "version-unused"</li>
|
||||
<li>gcc-4.0.x: "version-unused"</li>
|
||||
<li>gcc-4.1.x: "version-unused"</li>
|
||||
<li>gcc-4.2.x: "version-unused"</li>
|
||||
</ul>
|
||||
<p></p>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<p>
|
||||
Matching each specific C++ compiler release to a specific set of
|
||||
C++ include files. This is only implemented in gcc-3.1.1 releases
|
||||
and higher.
|
||||
</p>
|
||||
<p>
|
||||
All C++ includes are installed in include/c++, then nest in a
|
||||
directory hierarchy corresponding to the C++ compiler's released
|
||||
version. This version corresponds to the variable "gcc_version" in
|
||||
"libstdc++/acinclude.m4," and more details can be found in that
|
||||
file's macro GLIBCXX_CONFIGURE (GLIBCPP_CONFIGURE before gcc-3.4.0).
|
||||
</p>
|
||||
<p>
|
||||
C++ includes are versioned as follows:
|
||||
</p>
|
||||
<ul>
|
||||
<li>gcc-3.0.0: include/g++-v3</li>
|
||||
<li>gcc-3.0.1: include/g++-v3</li>
|
||||
<li>gcc-3.0.2: include/g++-v3</li>
|
||||
<li>gcc-3.0.3: include/g++-v3</li>
|
||||
<li>gcc-3.0.4: include/g++-v3</li>
|
||||
<li>gcc-3.1.0: include/g++-v3</li>
|
||||
<li>gcc-3.1.1: include/c++/3.1.1</li>
|
||||
<li>gcc-3.2.0: include/c++/3.2</li>
|
||||
<li>gcc-3.2.1: include/c++/3.2.1</li>
|
||||
<li>gcc-3.2.2: include/c++/3.2.2</li>
|
||||
<li>gcc-3.2.3: include/c++/3.2.3</li>
|
||||
<li>gcc-3.3.0: include/c++/3.3</li>
|
||||
<li>gcc-3.3.1: include/c++/3.3.1</li>
|
||||
<li>gcc-3.3.2: include/c++/3.3.2</li>
|
||||
<li>gcc-3.3.3: include/c++/3.3.3</li>
|
||||
<li>gcc-3.4.0: include/c++/3.4.0</li>
|
||||
<li>gcc-3.4.1: include/c++/3.4.1</li>
|
||||
<li>gcc-3.4.2: include/c++/3.4.2</li>
|
||||
<li>gcc-3.4.3: include/c++/3.4.3</li>
|
||||
<li>gcc-3.4.4: include/c++/3.4.4</li>
|
||||
<li>gcc-3.4.5: include/c++/3.4.5</li>
|
||||
<li>gcc-3.4.6: include/c++/3.4.6</li>
|
||||
<li>gcc-4.0.0: include/c++/4.0.0</li>
|
||||
<li>gcc-4.0.1: include/c++/4.0.1</li>
|
||||
<li>gcc-4.0.2: include/c++/4.0.2</li>
|
||||
<li>gcc-4.0.3: include/c++/4.0.3</li>
|
||||
<li>gcc-4.1.0: include/c++/4.1.0</li>
|
||||
<li>gcc-4.1.1: include/c++/4.1.1</li>
|
||||
<li>gcc-4.1.2: include/c++/4.1.2</li>
|
||||
<li>gcc-4.2.0: include/c++/4.2.0</li>
|
||||
</ul>
|
||||
<p></p>
|
||||
</li>
|
||||
</ul>
|
||||
<p>
|
||||
Taken together, these techniques can accurately specify interface
|
||||
and implementation changes in the GNU C++ tools themselves. Used
|
||||
properly, they allow both the GNU C++ tools implementation, and
|
||||
programs using them, an evolving yet controlled development that
|
||||
maintains backward compatibility.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
<h5 class="left">
|
||||
<a name="requirements"> Minimum requirements for a versioned ABI </a>
|
||||
</h5>
|
||||
<p>
|
||||
Minimum environment that supports a versioned ABI: A supported
|
||||
dynamic linker, a GNU linker of sufficient vintage to understand
|
||||
demangled C++ name globbing (ld), a shared executable compiled with
|
||||
g++, and shared libraries (libgcc_s, libstdc++) compiled by a
|
||||
compiler (g++) with a compatible ABI. Phew.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
On top of all that, an additional constraint: libstdc++ did not
|
||||
attempt to version symbols (or age gracefully, really) until version
|
||||
3.1.0.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Most modern Linux and BSD versions, particularly ones using
|
||||
gcc-3.1.x tools and more recent vintages, will meet the requirements above.
|
||||
</p>
|
||||
|
||||
|
||||
<h5 class="left">
|
||||
<a name="config"> What configure options impact symbol versioning? </a>
|
||||
</h5>
|
||||
<p>
|
||||
It turns out that most of the configure options that change default
|
||||
behavior will impact the mangled names of exported symbols, and thus
|
||||
impact versioning and compatibility.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For more information on configure options, including ABI impacts, see:
|
||||
http://gcc.gnu.org/onlinedocs/libstdc++/configopts.html
|
||||
</p>
|
||||
|
||||
<p>
|
||||
There is one flag that explicitly deals with symbol versioning:
|
||||
--enable-symvers.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In particular, libstdc++/acinclude.m4 has a macro called
|
||||
GLIBCXX_ENABLE_SYMVERS that defaults to yes (or the argument passed
|
||||
in via --enable-symvers=foo). At that point, the macro attempts to
|
||||
make sure that all the requirement for symbol versioning are in
|
||||
place. For more information, please consult acinclude.m4.
|
||||
</p>
|
||||
|
||||
|
||||
<h5 class="left">
|
||||
<a name="active"> How to tell if symbol versioning is, indeed, active? </a>
|
||||
</h5>
|
||||
<p>
|
||||
When the GNU C++ library is being built with symbol versioning on,
|
||||
you should see the following at configure time for libstdc++:
|
||||
</p>
|
||||
|
||||
|
||||
<code> checking versioning on shared library symbols... gnu</code>
|
||||
|
||||
<p>
|
||||
If you don't see this line in the configure output, or if this line
|
||||
appears but the last word is 'no', then you are out of luck.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If the compiler is pre-installed, a quick way to test is to compile
|
||||
the following (or any) simple C++ file and link it to the shared
|
||||
libstdc++ library:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
#include <iostream>
|
||||
|
||||
int main()
|
||||
{ std::cout << "hello" << std::endl; return 0; }
|
||||
|
||||
%g++ hello.cc -o hello.out
|
||||
|
||||
%ldd hello.out
|
||||
libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x00764000)
|
||||
libm.so.6 => /lib/tls/libm.so.6 (0x004a8000)
|
||||
libgcc_s.so.1 => /mnt/hd/bld/gcc/gcc/libgcc_s.so.1 (0x40016000)
|
||||
libc.so.6 => /lib/tls/libc.so.6 (0x0036d000)
|
||||
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00355000)
|
||||
|
||||
%nm hello.out
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
If you see symbols in the resulting output with "GLIBCXX_3" as part
|
||||
of the name, then the executable is versioned. Here's an example:
|
||||
</p>
|
||||
|
||||
<code> U _ZNSt8ios_base4InitC1Ev@@GLIBCXX_3.4 </code>
|
||||
|
||||
<h3 class="left">
|
||||
<a name="ABI_allowed">Library allowed ABI changes</a>
|
||||
</h3>
|
||||
<p>
|
||||
The following will cause the library minor version number to
|
||||
increase, say from "libstdc++.so.3.0.4" to "libstdc++.so.3.0.5".
|
||||
</p>
|
||||
<ul>
|
||||
<li>adding an exported global or static data member</li>
|
||||
<li>adding an exported function, static or non-virtual member function</li>
|
||||
<li>adding an exported symbol or symbols by additional instantiations</li>
|
||||
</ul>
|
||||
<p>
|
||||
</p>
|
||||
<p>
|
||||
Other allowed changes are possible.
|
||||
</p>
|
||||
|
||||
|
||||
<h3 class="left">
|
||||
<a name="ABI_disallowed">Library disallowed ABI changes</a>
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
The following non-exhaustive list will cause the library major version
|
||||
number to increase, say from "libstdc++.so.3.0.4" to
|
||||
"libstdc++.so.4.0.0".
|
||||
</p>
|
||||
<ul>
|
||||
<li>changes in the gcc/g++ compiler ABI</li>
|
||||
<li>changing size of an exported symbol</li>
|
||||
<li>changing alignment of an exported symbol</li>
|
||||
<li>changing the layout of an exported symbol</li>
|
||||
<li>changing mangling on an exported symbol</li>
|
||||
<li>deleting an exported symbol</li>
|
||||
<li>changing the inheritance properties of a type by adding or removing
|
||||
base classes</li>
|
||||
<li>
|
||||
changing the size, alignment, or layout of types
|
||||
specified in the C++ standard. These may not necessarily be
|
||||
instantiated or otherwise exported in the library binary, and
|
||||
include all the required locale facets, as well as things like
|
||||
std::basic_streambuf, et al.
|
||||
</li>
|
||||
|
||||
<li> adding an explicit copy constructor or destructor to a
|
||||
class that would otherwise have implicit versions. This will change
|
||||
the way the compiler deals with this class in by-value return
|
||||
statements or parameters: instead of being passing instances of this
|
||||
class in registers, the compiler will be forced to use memory. See <a
|
||||
href="http://www.codesourcery.com/cxx-abi/abi.html#calls"> this part</a>
|
||||
of the C++ ABI documentation for further details.
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
<h3 class="left">
|
||||
<a name="implementation">Library implementation strategy</a> </h3>
|
||||
|
||||
<ul>
|
||||
<li>Separation of interface and implementation
|
||||
<p>This is accomplished by two techniques that separate the API from
|
||||
the ABI: forcing undefined references to link against a library binary
|
||||
for definitions.
|
||||
</p>
|
||||
|
||||
<dl>
|
||||
<dt>Include files have declarations, source files have defines</dt>
|
||||
|
||||
<dd> For non-templatized types, such as much of <code>class
|
||||
locale</code>, the appropriate standard C++ include, say
|
||||
<code>locale</code>, can contain full declarations, while various
|
||||
source files (say <code> locale.cc, locale_init.cc,
|
||||
localename.cc</code>) contain definitions.</dd>
|
||||
|
||||
<dt>Extern template on required types</dt>
|
||||
|
||||
<dd>For parts of the standard that have an explicit list of required
|
||||
instantiations, the GNU extension syntax <code> extern template
|
||||
</code> can be used to control where template definitions
|
||||
reside. By marking required instantiations as <code> extern
|
||||
template </code> in include files, and providing explicit
|
||||
instantiations in the appropriate instantiation files, non-inlined
|
||||
template functions can be versioned. This technique is mostly used
|
||||
on parts of the standard that require <code> char</code> and <code>
|
||||
wchar_t</code> instantiations, and includes <code>
|
||||
basic_string</code>, the locale facets, and the types in <code>
|
||||
iostreams</code>.</dd>
|
||||
|
||||
</dl>
|
||||
<p> In addition, these techniques have the additional benefit that
|
||||
they reduce binary size, which can increase runtime performance.
|
||||
</p>
|
||||
</li>
|
||||
|
||||
<li>Namespaces linking symbol definitions to export mapfiles
|
||||
|
||||
<p>All symbols in the shared library binary are processed by a linker
|
||||
script at build time that either allows or disallows external
|
||||
linkage. Because of this, some symbols, regardless of normal C/C++
|
||||
linkage, are not visible. Symbols that are internal have several
|
||||
appealing characteristics: by not exporting the symbols, there are no
|
||||
relocations when the shared library is started and thus this makes for
|
||||
faster runtime loading performance by the underlying dynamic loading
|
||||
mechanism. In addition, they have the possibility of changing without
|
||||
impacting ABI compatibility.
|
||||
</p>
|
||||
|
||||
<p>The following namespaces are transformed by the mapfile:</p>
|
||||
|
||||
<dl>
|
||||
<dt><code>namespace std</code></dt>
|
||||
<dd> Defaults to exporting all symbols in label
|
||||
<code>GLIBCXX</code> that do not begin with an underscore, ie
|
||||
<code>__test_func</code> would not be exported by default. Select
|
||||
exceptional symbols are allowed to be visible.</dd>
|
||||
|
||||
<dt><code>namespace __gnu_cxx</code></dt>
|
||||
<dd> Defaults to not exporting any symbols in label
|
||||
<code>GLIBCXX</code>, select items are allowed to be visible.</dd>
|
||||
|
||||
<dt><code>namespace __gnu_internal</code></dt>
|
||||
<dd> Defaults to not exported, no items are allowed to be visible.</dd>
|
||||
|
||||
<dt><code>namespace __cxxabiv1</code>, aliased to <code> namespace abi</code></dt>
|
||||
<dd> Defaults to not exporting any symbols in label
|
||||
<code>CXXABI</code>, select items are allowed to be visible.</dd>
|
||||
</dl>
|
||||
<p>
|
||||
</p>
|
||||
</li>
|
||||
|
||||
<li>Freezing the API
|
||||
<p>Disallowed changes, as above, are not made on a stable release
|
||||
branch. Enforcement tends to be less strict with GNU extensions that
|
||||
standard includes.</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h3 class="left">
|
||||
<a name="ABI_testing">Testing ABI changes</a>
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
Testing for GNU C++ ABI changes is composed of two distinct areas:
|
||||
testing the C++ compiler (g++) for compiler changes, and testing the
|
||||
C++ library (libstdc++) for library changes.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Testing the C++ compiler ABI can be done various ways.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
One.
|
||||
Intel ABI checker. More information can be obtained
|
||||
<a href="http://developer.intel.com/software/products/opensource/">here.</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Two.
|
||||
The second is yet unreleased, but has been announced on the gcc
|
||||
mailing list. It is yet unspecified if these tools will be freely
|
||||
available, and able to be included in a GNU project. Please contact
|
||||
Mark Mitchell (mark@codesourcery.com) for more details, and current
|
||||
status.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Three.
|
||||
Involves using the vlad.consistency test framework. This has also been
|
||||
discussed on the gcc mailing lists.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Testing the C++ library ABI can also be done various ways.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
One.
|
||||
(Brendan Kehoe, Jeff Law suggestion to run 'make check-c++' two ways,
|
||||
one with a new compiler and an old library, and the other with an old
|
||||
compiler and a new library, and look for testsuite regressions)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Details on how to set this kind of test up can be found here:
|
||||
http://gcc.gnu.org/ml/gcc/2002-08/msg00142.html
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Two.
|
||||
Use the 'make check-abi' rule in the libstdc++ Makefile.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This is a proactive check the library ABI. Currently, exported symbol
|
||||
names that are either weak or defined are checked against a last known
|
||||
good baseline. Currently, this baseline is keyed off of 3.4.0
|
||||
binaries, as this was the last time the .so number was incremented. In
|
||||
addition, all exported names are demangled, and the exported objects
|
||||
are checked to make sure they are the same size as the same object in
|
||||
the baseline.
|
||||
|
||||
Notice that each baseline is relative to a <strong>default</strong>
|
||||
configured library and compiler: in particular, if options such as
|
||||
--enable-clocale, or --with-cpu, in case of multilibs, are used at
|
||||
configure time, the check may fail, either because of substantive
|
||||
differences or because of limitations of the current checking
|
||||
machinery.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This dataset is insufficient, yet a start. Also needed is a
|
||||
comprehensive check for all user-visible types part of the standard
|
||||
library for sizeof() and alignof() changes.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Verifying compatible layouts of objects is not even attempted. It
|
||||
should be possible to use sizeof, alignof, and offsetof to compute
|
||||
offsets for each structure and type in the standard library, saving to
|
||||
another datafile. Then, compute this in a similar way for new
|
||||
binaries, and look for differences.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Another approach might be to use the -fdump-class-hierarchy flag to
|
||||
get information. However, currently this approach gives insufficient
|
||||
data for use in library testing, as class data members, their offsets,
|
||||
and other detailed data is not displayed with this flag.
|
||||
(See g++/7470 on how this was used to find bugs.)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Perhaps there are other C++ ABI checkers. If so, please notify
|
||||
us. We'd like to know about them!
|
||||
</p>
|
||||
|
||||
<h3 class="left">
|
||||
<a name="ABI_multi_testing">Testing Multi-ABI binaries</a>
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
A "C" application, dynamically linked to two shared libraries, liba,
|
||||
libb. The dependent library liba is C++ shared library compiled with
|
||||
gcc-3.3.x, and uses io, exceptions, locale, etc. The dependent library
|
||||
libb is a C++ shared library compiled with gcc-3.4.x, and also uses io,
|
||||
exceptions, locale, etc.
|
||||
</p>
|
||||
|
||||
<p> As above, libone is constructed as follows: </p>
|
||||
<pre>
|
||||
%$bld/H-x86-gcc-3.4.0/bin/g++ -fPIC -DPIC -c a.cc
|
||||
|
||||
%$bld/H-x86-gcc-3.4.0/bin/g++ -shared -Wl,-soname -Wl,libone.so.1 -Wl,-O1 -Wl,-z,defs a.o -o libone.so.1.0.0
|
||||
|
||||
%ln -s libone.so.1.0.0 libone.so
|
||||
|
||||
%$bld/H-x86-gcc-3.4.0/bin/g++ -c a.cc
|
||||
|
||||
%ar cru libone.a a.o
|
||||
</pre>
|
||||
|
||||
<p> And, libtwo is constructed as follows: </p>
|
||||
|
||||
<pre>
|
||||
%$bld/H-x86-gcc-3.3.3/bin/g++ -fPIC -DPIC -c b.cc
|
||||
|
||||
%$bld/H-x86-gcc-3.3.3/bin/g++ -shared -Wl,-soname -Wl,libtwo.so.1 -Wl,-O1 -Wl,-z,defs b.o -o libtwo.so.1.0.0
|
||||
|
||||
%ln -s libtwo.so.1.0.0 libtwo.so
|
||||
|
||||
%$bld/H-x86-gcc-3.3.3/bin/g++ -c b.cc
|
||||
|
||||
%ar cru libtwo.a b.o
|
||||
</pre>
|
||||
|
||||
<p> ...with the resulting libraries looking like </p>
|
||||
<pre>
|
||||
%ldd libone.so.1.0.0
|
||||
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x40016000)
|
||||
libm.so.6 => /lib/tls/libm.so.6 (0x400fa000)
|
||||
libgcc_s.so.1 => /mnt/hd/bld/gcc/gcc/libgcc_s.so.1 (0x4011c000)
|
||||
libc.so.6 => /lib/tls/libc.so.6 (0x40125000)
|
||||
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00355000)
|
||||
|
||||
%ldd libtwo.so.1.0.0
|
||||
libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x40027000)
|
||||
libm.so.6 => /lib/tls/libm.so.6 (0x400e1000)
|
||||
libgcc_s.so.1 => /mnt/hd/bld/gcc/gcc/libgcc_s.so.1 (0x40103000)
|
||||
libc.so.6 => /lib/tls/libc.so.6 (0x4010c000)
|
||||
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00355000)
|
||||
|
||||
</pre>
|
||||
|
||||
<p> Then, the "C" compiler is used to compile a source file that uses
|
||||
functions from each library.</p>
|
||||
<pre>
|
||||
gcc test.c -g -O2 -L. -lone -ltwo /usr/lib/libstdc++.so.5 /usr/lib/libstdc++.so.6
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Which gives the expected:
|
||||
</p>
|
||||
<pre>
|
||||
%ldd a.out
|
||||
libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x00764000)
|
||||
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x40015000)
|
||||
libc.so.6 => /lib/tls/libc.so.6 (0x0036d000)
|
||||
libm.so.6 => /lib/tls/libm.so.6 (0x004a8000)
|
||||
libgcc_s.so.1 => /mnt/hd/bld/gcc/gcc/libgcc_s.so.1 (0x400e5000)
|
||||
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x00355000)
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
This resulting binary, when executed, will be able to safely use code
|
||||
from both liba, and the dependent libstdc++.so.6, and libb, with the
|
||||
dependent libstdc++.so.5.
|
||||
</p>
|
||||
|
||||
|
||||
<h3 class="left">
|
||||
<a name="Outstanding Issues">Outstanding Issues</a>
|
||||
</h3>
|
||||
|
||||
<p> Some features in the C++ language make versioning especially
|
||||
difficult. In particular, compiler generated constructs such as
|
||||
implicit instantiations for templates, typeinfo information, and
|
||||
virtual tables all may cause ABI leakage across shared library
|
||||
boundaries. Because of this, mixing C++ ABI's is not recommended at
|
||||
this time.
|
||||
</p>
|
||||
|
||||
<p>For more background on this issue, see these bugzilla entries:</p>
|
||||
|
||||
<p>
|
||||
<a href="http://gcc.gnu.org/PR24660">24660: versioning weak symbols in libstdc++</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<a href="http://gcc.gnu.org/PR19664">19664: libstdc++ headers should have pop/push of the visibility around the declarations</a>
|
||||
</p>
|
||||
|
||||
<h3 class="left">
|
||||
<a name="references">Bibliography / Further Reading</a>
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
ABIcheck, a vague idea of checking ABI compatibility
|
||||
<br />
|
||||
<a href="http://abicheck.sourceforge.net/">http://abicheck.sourceforge.net/</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
C++ ABI reference
|
||||
<br />
|
||||
<a href="http://www.codesourcery.com/cxx-abi/">http://www.codesourcery.com/cxx-abi/</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Intel ABI documentation, "Intel® Compilers for Linux* -Compatibility with the GNU Compilers"
|
||||
<br />
|
||||
<a href="http://developer.intel.com/software/products/compilers/techtopics/LinuxCompilersCompatibility.htm">http://developer.intel.com/software/products/compilers/techtopics/LinuxCompilersCompatibility.htm</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Sun Solaris 2.9 docs
|
||||
<br />
|
||||
Linker and Libraries Guide (document 816-1386)
|
||||
<br />
|
||||
C++ Migration Guide (document 816-2459)
|
||||
<br />
|
||||
<a href="http://docs.sun.com/db/prod/solaris.9">http://docs.sun.com/db/prod/solaris.9</a>
|
||||
<br />
|
||||
<a href="http://docs.sun.com/?p=/doc/816-1386&a=load">http://docs.sun.com/?p=/doc/816-1386&a=load</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Ulrich Drepper, "ELF Symbol Versioning"
|
||||
<br />
|
||||
<a href="http://people.redhat.com/drepper/symbol-versioning">http://people.redhat.com/drepper/symbol-versioning</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
C++ ABI for the ARM Architecture
|
||||
<br />
|
||||
<a href="http://www.arm.com/miscPDFs/8033.pdf">http://www.arm.com/miscPDFs/8033.pdf</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Benjamin Kosnik, ISO C++ J16/06-0046
|
||||
<br />
|
||||
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n1976.html">Dynamic Shared Objects: Survey and Issues</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Benjamin Kosnik, ISO C++ J16/06-0083
|
||||
<br />
|
||||
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2013.html">Versioning With Namespaces</a>
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,290 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta name="AUTHOR" content="bkoz@gcc.gnu.org (Benjamin Kosnik)" />
|
||||
<meta name="KEYWORDS" content="C++, libstdc++, API, evolution, deprecate" />
|
||||
<meta name="DESCRIPTION" content="API evolution and deprecation history" />
|
||||
<meta name="GENERATOR" content="emacs and ten fingers" />
|
||||
<title>API Evolution and Deprecation History</title>
|
||||
<link rel="StyleSheet" href="lib3styles.css" type="text/css" />
|
||||
<link rel="Start" href="documentation.html" type="text/html"
|
||||
title="GNU C++ Standard Library" />
|
||||
<link rel="Copyright" href="17_intro/license.html" type="text/html" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 class="centered"><a name="top">API Evolution and Deprecation History</a></h1>
|
||||
|
||||
<p class="fineprint"><em>
|
||||
The latest version of this document is always available at
|
||||
<a href="http://gcc.gnu.org/onlinedocs/libstdc++/17_intro/api.html">
|
||||
http://gcc.gnu.org/onlinedocs/libstdc++/17_intro/api.html</a>.
|
||||
</em></p>
|
||||
|
||||
<p><em>
|
||||
To the <a href="http://gcc.gnu.org/libstdc++/">libstdc++ homepage</a>.
|
||||
</em></p>
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<hr />
|
||||
<h3 class="left">
|
||||
<a name="intro">API Evolution, Deprecation, and History of User Visible Changes</a>
|
||||
</h3>
|
||||
|
||||
<p> A list of user-visible changes, by release version.
|
||||
</p>
|
||||
|
||||
<h3 class="left">
|
||||
<a name="3.0">3.0</a>
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
Extensions moved to <code>include/ext</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Include files from the SGI/HP sources that pre-date the ISO standard
|
||||
are added. These files are placed into
|
||||
the <code>include/backward</code> directory and a deprecated warning
|
||||
is added that notifies on inclusion (<code>-Wno-deprecated</code>
|
||||
deactivates the warning.)
|
||||
</p>
|
||||
|
||||
<p>Deprecated include <backward/strstream> added.</p>
|
||||
|
||||
<p>Removal of include <builtinbuf.h>, <indstream.h>, <parsestream.h>, <PlotFile.h>, <SFile.h>, <stdiostream.h>, and <stream.h>.</p>
|
||||
|
||||
|
||||
<h3 class="left">
|
||||
<a name="3.1">3.1</a>
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
Extensions from SGI/HP moved from <code>namespace std</code>
|
||||
to <code>namespace __gnu_cxx</code>. As part of this, the following
|
||||
new includes are
|
||||
added: <ext/algorithm>, <ext/functional>, <ext/iterator>, <ext/memory>, and <ext/numeric>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Extensions to <code>basic_filebuf</code> introduced: <code>__gnu_cxx::enc_filebuf</code>, and <code>__gnu_cxx::stdio_filebuf</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Extensions to tree data structures added in <ext/rb_tree>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Removal of <ext/tree>, moved to <backward/tree.h>.
|
||||
</p>
|
||||
|
||||
|
||||
<h3 class="left">
|
||||
<a name="3.2">3.2</a>
|
||||
</h3>
|
||||
<p>Symbol versioning introduced for shared library.</p>
|
||||
|
||||
<p>Removal of include <backward/strstream.h>.</p>
|
||||
|
||||
<h3 class="left">
|
||||
<a name="3.3">3.3</a>
|
||||
</h3>
|
||||
<p>Allocator changes. Change <code>__malloc_alloc</code> to <code>malloc_allocator</code> and <code>__new_alloc</code> to <code>new_allocator</code>. </p>
|
||||
|
||||
<p>Error handling in iostreams cleaned up, made consistent. </p>
|
||||
|
||||
|
||||
<h3 class="left">
|
||||
<a name="3.4">3.4</a>
|
||||
</h3>
|
||||
<p>
|
||||
Large file support.
|
||||
</p>
|
||||
|
||||
<p> Extensions for generic characters and <code>char_traits</code> added in <ext/pod_char_traits.h>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Support for <code>wchar_t</code> specializations of <code>basic_filebuf</code> enhanced to support <code>UTF-8</code> and <code>Unicode</code>, depending on host. More hosts support basic <code>wchar_t</code> functionality.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Support for <code>char_traits</code> beyond builtin types.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Conformant <code>allocator</code> class and usage in containers. As
|
||||
part of this, the following extensions are
|
||||
added: <ext/bitmap_allocator.h>, <ext/debug_allocator.h>, <ext/mt_allocator.h>, <ext/malloc_allocator.h>,<ext/new_allocator.h>, <ext/pool_allocator.h>.
|
||||
</p>
|
||||
|
||||
|
||||
<p>
|
||||
Debug mode first appears.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
PCH support.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Macro guard for libstdc++ changed, from _GLIBCPP_ to _GLIBCXX_.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Extension <ext/stdio_sync_filebuf.h> added.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Extension <ext/demangle.h> added.
|
||||
</p>
|
||||
|
||||
|
||||
<h3 class="left">
|
||||
<a name="4.0">4.0</a>
|
||||
</h3>
|
||||
<p>
|
||||
TR1 features first appear.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Extension allocator <ext/array_allocator.h> added.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Extension <code>codecvt</code> specializations moved to <ext/codecvt_specializations.h>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Removal of <ext/demangle.h>.
|
||||
</p>
|
||||
|
||||
|
||||
<h3 class="left">
|
||||
<a name="4.1">4.1</a>
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
Removal of <cassert> from all standard headers: now has to be explicitly included for <code>std::assert</code> calls.
|
||||
</p>
|
||||
|
||||
<p> Extensions for policy-based data structures first added. New includes,
|
||||
types, namespace <code>pb_assoc</code>.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
<p> Extensions for typelists added in <ext/typelist.h>.
|
||||
</p>
|
||||
|
||||
<p> Extension for policy-based <code>basic_string</code> first added: <code>__gnu_cxx::__versa_string</code> in <ext/vstring.h>.
|
||||
</p>
|
||||
|
||||
<h3 class="left">
|
||||
<a name="4.2">4.2</a>
|
||||
</h3>
|
||||
|
||||
<p> Default visibility attributes applied to <code>namespace std</code>. Support for <code>-fvisibility</code>.
|
||||
</p>
|
||||
|
||||
<p>TR1 <random>, <complex>, and C compatibility headers added.</p>
|
||||
|
||||
<p> Extensions for concurrent programming consolidated
|
||||
into <ext/concurrence.h> and <ext/atomicity.h>,
|
||||
including change of namespace to <code>__gnu_cxx</code> in some
|
||||
cases. Added types
|
||||
include <code>_Lock_policy</code>, <code>__concurrence_lock_error</code>, <code>__concurrence_unlock_error</code>, <code>__mutex</code>, <code>__scoped_lock</code>.</p>
|
||||
|
||||
<p> Extensions for type traits consolidated
|
||||
into <ext/type_traits.h>. Additional traits are added
|
||||
(<code>__conditional_type</code>, <code>__enable_if</code>, others.)
|
||||
</p>
|
||||
|
||||
<p> Extensions for policy-based data structures revised. New includes,
|
||||
types, namespace moved to <code>__pb_ds</code>.
|
||||
</p>
|
||||
|
||||
<p> Extensions for debug mode modified: now nested in <code>namespace
|
||||
std::__debug</code> and extensions in <code>namespace
|
||||
__gnu_cxx::__debug</code>.</p>
|
||||
|
||||
<p> Extensions added: <ext/typelist.h>
|
||||
and <ext/throw_allocator.h>.
|
||||
</p>
|
||||
|
||||
<h3 class="left">
|
||||
<a name="4.3">4.3</a>
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
C++0X features first appear.
|
||||
</p>
|
||||
|
||||
<p>TR1 <regex> and <cmath>'s mathematical special function added.</p>
|
||||
|
||||
<p>
|
||||
Backward include edit.
|
||||
</p>
|
||||
<ul>
|
||||
<li> Removed: <algobase.h> <algo.h> <alloc.h> <bvector.h> <complex.h>
|
||||
defalloc.h> <deque.h> <fstream.h> <function.h> <hash_map.h> <hash_set.h>
|
||||
hashtable.h> <heap.h> <iomanip.h> <iostream.h> <istream.h> <iterator.h>
|
||||
list.h> <map.h> <multimap.h> <multiset.h> <new.h> <ostream.h> <pair.h> <queue.h> <rope.h> <set.h> <slist.h> <stack.h> <streambuf.h> <stream.h> <tempbuf.h>
|
||||
<tree.h> <vector.h>
|
||||
</li>
|
||||
<li> Added: <hash_map> and <hash_set></li>
|
||||
<li> Added in C++0x: <auto_ptr.h> and <binders.h></li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Header dependency streamlining.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><algorithm> no longer includes <climits>, <cstring>, or <iosfwd> </li>
|
||||
<li><bitset> no longer includes <istream> or <ostream>, adds <iosfwd> </li>
|
||||
<li><functional> no longer includes <cstddef></li>
|
||||
<li><iomanip> no longer includes <istream>, <istream>, or <functional>, adds <ioswd> </li>
|
||||
<li><numeric> no longer includes <iterator></li>
|
||||
<li><string> no longer includes <algorithm> or <memory></li>
|
||||
|
||||
<li><valarray> no longer includes <numeric> or <cstdlib></li>
|
||||
<li><tr1/hashtable> no longer includes <memory> or <functional></li>
|
||||
<li><tr1/memory> no longer includes <algorithm></li>
|
||||
<li><tr1/random> no longer includes <algorithm> or <fstream></li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Debug mode for <unordered_map> and <unordered_set>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Parallel mode first appears.
|
||||
</p>
|
||||
|
||||
<p>Variadic template implementations of items in <tuple> and
|
||||
<functional>.
|
||||
</p>
|
||||
|
||||
<p>Default <code>what</code> implementations give more elaborate
|
||||
exception strings for <code>bad_cast</code>,
|
||||
<code>bad_typeid</code>, <code>bad_exception</code>, and
|
||||
<code>bad_alloc</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
PCH binary files no longer installed. Instead, the source files are installed.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Namespace pb_ds moved to __gnu_pb_ds.
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -1,14 +0,0 @@
|
|||
# Blatantly ripped out of the graphviz examples and modified. -pme
|
||||
digraph v3conf {
|
||||
size="6,6";
|
||||
node [color=lightblue2, style=filled];
|
||||
"aclocal.m4" -> "acinclude.m4";
|
||||
"configure" -> "aclocal.m4";
|
||||
"configure" -> "configure.ac";
|
||||
"configure" -> "crossconfig.m4";
|
||||
"configure" -> "linkage.m4";
|
||||
"[*/]Makefile.in" -> "Makefile.am";
|
||||
"[*/]Makefile.in" -> "configure.ac";
|
||||
"config.h.in" -> "acconfig.h";
|
||||
"config.h.in" -> "configure.ac";
|
||||
}
|
Binary file not shown.
Before Width: | Height: | Size: 3.4 KiB |
|
@ -1,305 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta name="AUTHOR" content="pme@gcc.gnu.org (Phil Edwards)" />
|
||||
<meta name="DESCRIPTION" content="configury for libstdc++" />
|
||||
<meta name="GENERATOR" content="vi and eight fingers" />
|
||||
<title>libstdc++ configury</title>
|
||||
<link rel="StyleSheet" href="../lib3styles.css" type='text/css' />
|
||||
<link rel="Start" href="../documentation.html" type="text/html"
|
||||
title="GNU C++ Standard Library" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1><code>> open configury door</code></h1>
|
||||
<h1><code>> look</code></h1>
|
||||
|
||||
<p class="larger"><code>You are in a maze of twisty passages, all
|
||||
different.</code></p>
|
||||
<p class="larger"><code>It is dark. You are likely to be eaten by a
|
||||
Canadian cross build.</code></p>
|
||||
|
||||
|
||||
<hr />
|
||||
<h2>Notes on libstdc++ configury</h2>
|
||||
<blockquote>
|
||||
No problem is insoluble in all conceivable circumstances.<br />
|
||||
-- The Cosmic AC,
|
||||
<a href="http://mit.edu/tylerc/www/twt/LQ1.htm">The
|
||||
Last Question</a>, by Isaac Asimov
|
||||
</blockquote>
|
||||
<ul>
|
||||
<li><a href="#prereq">Prerequisites for configure and make hacking</a></li>
|
||||
<li><a href="#deps">Overview: what comes from where</a></li>
|
||||
<li><a href="#breakout">Storing information in non-AC files, like
|
||||
configure.host</a></li>
|
||||
<li><a href="#general">Coding and commenting conventions</a></li>
|
||||
<li><a href="#aclayout">The acinclude.m4 layout</a></li>
|
||||
<li><a href="#enable"><code>GLIBCXX_ENABLE, the --enable</code> howto</a></li>
|
||||
</ul>
|
||||
|
||||
<hr />
|
||||
<h3><a name="prereq">Prerequisites for configure and make hacking</a></h3>
|
||||
|
||||
<p> As
|
||||
noted <a href="http://gcc.gnu.org/install/prerequisites.html">previously</a>,
|
||||
certain other tools are necessary for hacking on files that control
|
||||
configure (<code>configure.ac</code>, <code>acinclude.m4</code>) and
|
||||
make (<code>Makefile.am</code>). These additional tools
|
||||
(<code>automake</code>, and <code>autoconf</code>) are further
|
||||
described in detail in their respective manuals. All the libraries in GCC try to stay in sync with each other in terms of versions of the auto-tools used, so please try to play nicely with the neighbors.
|
||||
</p>
|
||||
|
||||
|
||||
<hr />
|
||||
<h3><a name="deps">Overview: what comes from where</a></h3>
|
||||
<p class="centered"><img src="confdeps.png"
|
||||
alt="Dependency graph in PNG graphics format. (Get a better browser!)" /></p>
|
||||
|
||||
<p>Regenerate all generated files by using the command sequence
|
||||
<code>"autoreconf"</code> at the top level of the libstdc++ source
|
||||
directory. The following will also work, but is much more complex:
|
||||
<code>"aclocal-1.7 && autoconf-2.59 &&
|
||||
autoheader-2.59 && automake-1.7"</code> The version numbers
|
||||
may be absent entirely or otherwise vary depending on
|
||||
<a href="http://gcc.gnu.org/install/prerequisites.html">the current
|
||||
requirements</a> and your vendor's choice of installation names.
|
||||
</p>
|
||||
|
||||
|
||||
<hr />
|
||||
<h3><a name="breakout">Storing information in non-AC files, like
|
||||
configure.host</a></h3>
|
||||
<p>Until that glorious day when we can use AC_TRY_LINK with a cross-compiler,
|
||||
we have to hardcode the results of what the tests would have shown if
|
||||
they could be run. So we have an inflexible mess like crossconfig.m4.
|
||||
</p>
|
||||
|
||||
<p>Wouldn't it be nice if we could store that information in files like
|
||||
configure.host, which can be modified without needing to regenerate
|
||||
anything, and can even be tweaked without really knowing how the configury
|
||||
all works? Perhaps break the pieces of crossconfig.m4 out and place them in
|
||||
their appropriate config/{cpu,os} directory.
|
||||
</p>
|
||||
|
||||
<p>Alas, writing macros like "<code>AC_DEFINE(HAVE_A_NICE_DAY)</code>" can
|
||||
only be done inside files which are passed through autoconf. Files which
|
||||
are pure shell script can be source'd at configure time. Files which
|
||||
contain autoconf macros must be processed with autoconf. We could still
|
||||
try breaking the pieces out into "config/*/cross.m4" bits, for instance,
|
||||
but then we would need arguments to aclocal/autoconf to properly find
|
||||
them all when generating configure. I would discourage that.
|
||||
</p>
|
||||
|
||||
|
||||
<hr />
|
||||
<h3><a name="general">Coding and commenting conventions</a></h3>
|
||||
<p>Lots of stuff got thrown out because the new autotools kindly generate
|
||||
the same (or better) shell code for us.
|
||||
</p>
|
||||
|
||||
<p>Most comments should use {octothorpes, shibboleths, hash marks, pound
|
||||
signs, whatevers} rather than "dnl". Nearly all comments in configure.ac
|
||||
should. Comments inside macros written in ancilliary .m4 files should.
|
||||
About the only comments which should <em>not</em> use #, but use dnl
|
||||
instead, are comments <em>outside</em> our own macros in the ancilliary
|
||||
files. The difference is that # comments show up in <code>configure</code>
|
||||
(which is most helpful for debugging), while dnl'd lines just vanish.
|
||||
Since the macros in ancilliary files generate code which appears in odd
|
||||
places, their "outside" comments tend to not be useful while reading
|
||||
<code>configure</code>.
|
||||
</p>
|
||||
|
||||
<p>Do not use any <code>$target*</code> variables, such as
|
||||
<code>$target_alias</code>. The single exception is in configure.ac,
|
||||
for automake+dejagnu's sake.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h3><a name="aclayout">The acinclude.m4 layout</a></h3>
|
||||
<p>The nice thing about acinclude.m4/aclocal.m4 is that macros aren't actually
|
||||
performed/called/expanded/whatever here, just loaded. So we can arrange
|
||||
the contents however we like. As of this writing, acinclude.m4 is arranged
|
||||
as follows:
|
||||
</p>
|
||||
<pre>
|
||||
GLIBCXX_CHECK_HOST
|
||||
GLIBCXX_TOPREL_CONFIGURE
|
||||
GLIBCXX_CONFIGURE
|
||||
</pre>
|
||||
<p>All the major variable "discovery" is done here. CXX, multilibs, etc.
|
||||
</p>
|
||||
<pre>
|
||||
fragments included from elsewhere
|
||||
</pre>
|
||||
<p>Right now, "fragments" == "the math/linkage bits".
|
||||
</p>
|
||||
<pre>
|
||||
GLIBCXX_CHECK_COMPILER_FEATURES
|
||||
GLIBCXX_CHECK_LINKER_FEATURES
|
||||
GLIBCXX_CHECK_WCHAR_T_SUPPORT
|
||||
</pre>
|
||||
<p>Next come extra compiler/linker feature tests. Wide character support
|
||||
was placed here because I couldn't think of another place for it. It will
|
||||
probably get broken apart like the math tests, because we're still disabling
|
||||
wchars on systems which could actually support them.
|
||||
</p>
|
||||
<pre>
|
||||
GLIBCXX_CHECK_SETRLIMIT_ancilliary
|
||||
GLIBCXX_CHECK_SETRLIMIT
|
||||
GLIBCXX_CHECK_S_ISREG_OR_S_IFREG
|
||||
GLIBCXX_CHECK_POLL
|
||||
GLIBCXX_CHECK_WRITEV
|
||||
|
||||
GLIBCXX_CONFIGURE_TESTSUITE
|
||||
</pre>
|
||||
<p>Feature tests which only get used in one place. Here, things used only in
|
||||
the testsuite, plus a couple bits used in the guts of I/O.
|
||||
</p>
|
||||
<pre>
|
||||
GLIBCXX_EXPORT_INCLUDES
|
||||
GLIBCXX_EXPORT_FLAGS
|
||||
GLIBCXX_EXPORT_INSTALL_INFO
|
||||
</pre>
|
||||
<p>Installation variables, multilibs, working with the rest of the compiler.
|
||||
Many of the critical variables used in the makefiles are set here.
|
||||
</p>
|
||||
<pre>
|
||||
GLIBGCC_ENABLE
|
||||
GLIBCXX_ENABLE_C99
|
||||
GLIBCXX_ENABLE_CHEADERS
|
||||
GLIBCXX_ENABLE_CLOCALE
|
||||
GLIBCXX_ENABLE_CONCEPT_CHECKS
|
||||
GLIBCXX_ENABLE_CSTDIO
|
||||
GLIBCXX_ENABLE_CXX_FLAGS
|
||||
GLIBCXX_ENABLE_C_MBCHAR
|
||||
GLIBCXX_ENABLE_DEBUG
|
||||
GLIBCXX_ENABLE_DEBUG_FLAGS
|
||||
GLIBCXX_ENABLE_LONG_LONG
|
||||
GLIBCXX_ENABLE_PCH
|
||||
GLIBCXX_ENABLE_SJLJ_EXCEPTIONS
|
||||
GLIBCXX_ENABLE_SYMVERS
|
||||
GLIBCXX_ENABLE_THREADS
|
||||
</pre>
|
||||
<p>All the features which can be controlled with enable/disable configure
|
||||
options. Note how they're alphabetized now? Keep them like that. :-)
|
||||
</p>
|
||||
<pre>
|
||||
AC_LC_MESSAGES
|
||||
libtool bits
|
||||
</pre>
|
||||
<p>Things which we don't seem to use directly, but just has to be present
|
||||
otherwise stuff magically goes wonky.
|
||||
</p>
|
||||
|
||||
|
||||
<hr />
|
||||
<h3><a name="enable">GLIBCXX_ENABLE, the <code>--enable</code> howto</a></h3>
|
||||
<p>All the GLIBCXX_ENABLE_FOO macros use a common helper, GLIBCXX_ENABLE.
|
||||
(You don't have to use it, but it's easy.) The helper does two things
|
||||
for us:
|
||||
</p>
|
||||
|
||||
<ol>
|
||||
<li>Builds the call to the AC_ARG_ENABLE macro, with --help text properly
|
||||
quoted and aligned. (Death to changequote!)</li>
|
||||
<li>Checks the result against a list of allowed possibilities, and signals
|
||||
a fatal error if there's no match. This means that the rest of the
|
||||
GLIBCXX_ENABLE_FOO macro doesn't need to test for strange arguments,
|
||||
nor do we need to protect against empty/whitespace strings with the
|
||||
<code>"x$foo" = "xbar"</code> idiom.</li>
|
||||
</ol>
|
||||
|
||||
<p>Doing these things correctly takes some extra autoconf/autom4te code,
|
||||
which made our macros nearly illegible. So all the ugliness is factored
|
||||
out into this one helper macro.
|
||||
</p>
|
||||
|
||||
<p>Many of the macros take an argument, passed from when they are expanded
|
||||
in configure.ac. The argument controls the default value of the
|
||||
enable/disable switch. Previously, the arguments themselves had defaults.
|
||||
Now they don't, because that's extra complexity with zero gain for us.
|
||||
</p>
|
||||
|
||||
<p>There are three "overloaded signatures". When reading the descriptions
|
||||
below, keep in mind that the brackets are autoconf's quotation characters,
|
||||
and that they will be stripped. Examples of just about everything occur
|
||||
in acinclude.m4, if you want to look.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
GLIBCXX_ENABLE (FEATURE, DEFAULT, HELP-ARG, HELP-STRING)
|
||||
GLIBCXX_ENABLE (FEATURE, DEFAULT, HELP-ARG, HELP-STRING, permit a|b|c)
|
||||
GLIBCXX_ENABLE (FEATURE, DEFAULT, HELP-ARG, HELP-STRING, SHELL-CODE-HANDLER)
|
||||
</pre>
|
||||
|
||||
<ul>
|
||||
<li><p>FEATURE is the string that follows --enable. The results of the test
|
||||
(such as it is) will be in the variable $enable_FEATURE, where FEATURE
|
||||
has been squashed. Example: <code>[extra-foo]</code>, controlled by the
|
||||
--enable-extra-foo option and stored in $enable_extra_foo.</p></li>
|
||||
<li><p>DEFAULT is the value to store in $enable_FEATURE if the user does not
|
||||
pass --enable/--disable. It should be one of the permitted values
|
||||
passed later. Examples: <code>[yes]</code>, or <code>[bar]</code>, or
|
||||
<code>[$1]</code> (which passes the argument given to the
|
||||
GLIBCXX_ENABLE_FOO macro as the default).</p>
|
||||
<p>For cases where we need to probe for particular models
|
||||
of things, it is useful to have an undocumented "auto" value here (see
|
||||
GLIBCXX_ENABLE_CLOCALE for an example).</p></li>
|
||||
<li><p>HELP-ARG is any text to append to the option string itself in the
|
||||
--help output. Examples: <code>[]</code> (i.e., an empty string,
|
||||
which appends nothing),
|
||||
<code>[=BAR]</code>, which produces
|
||||
<code>--enable-extra-foo=BAR</code>, and
|
||||
<code>[@<:@=BAR@:>@]</code>, which produces
|
||||
<code>--enable-extra-foo[=BAR]</code>. See the difference? See what
|
||||
it implies to the user?</p>
|
||||
<p>If you're wondering what that line noise in the last example was,
|
||||
that's how you embed autoconf special characters in output text.
|
||||
They're called
|
||||
<a
|
||||
href="http://www.gnu.org/software/autoconf/manual/autoconf-2.57/html_node/autoconf_95.html#SEC95"><em>quadrigraphs</em></a>
|
||||
and you should use them whenever necessary.</p></li>
|
||||
<li><p>HELP-STRING is what you think it is. Do not include the "default"
|
||||
text like we used to do; it will be done for you by GLIBCXX_ENABLE.
|
||||
By convention, these are not full English sentences.
|
||||
Example: [turn on extra foo]</p></li>
|
||||
</ul>
|
||||
|
||||
<p>With no other arguments, only the standard autoconf patterns are
|
||||
allowed: "<code>--{enable,disable}-foo[={yes,no}]</code>" The
|
||||
$enable_FEATURE variable is guaranteed to equal either "yes" or "no"
|
||||
after the macro. If the user tries to pass something else, an
|
||||
explanatory error message will be given, and configure will halt.
|
||||
</p>
|
||||
|
||||
<p>The second signature takes a fifth argument,
|
||||
"<code>[permit <em>a</em>|<em>b</em>|<em>c</em>|<em>...</em>]</code>"
|
||||
This allows <em>a</em> or <em>b</em> or ... after the equals sign in the
|
||||
option, and $enable_FEATURE is guaranteed to equal one of them after the
|
||||
macro. Note that if you want to allow plain --enable/--disable with no
|
||||
"=whatever", you must include "yes" and "no" in the list of permitted
|
||||
values. Also note that whatever you passed as DEFAULT must be in the list.
|
||||
If the user tries to pass something not on the list, a semi-explanatory
|
||||
error message will be given, and configure will halt.
|
||||
Example: <code>[permit generic|gnu|ieee_1003.1-2001|yes|no|auto]</code>
|
||||
</p>
|
||||
|
||||
<p>The third signature takes a fifth argument. It is arbitrary shell code
|
||||
to execute if the user actually passes the enable/disable option. (If
|
||||
the user does not, the default is used. Duh.) No argument checking at
|
||||
all is done in this signature. See GLIBCXX_ENABLE_CXX_FLAGS for an
|
||||
example of handling, and an error message.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
</body>
|
||||
</html>
|
|
@ -1,135 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<title>How to contribute</title>
|
||||
<link rel="StyleSheet" href="../lib3styles.css" type="text/css" />
|
||||
<link rel="Start" href="../documentation.html" type="text/html"
|
||||
title="GNU C++ Standard Library" />
|
||||
<link rel="Help" href="../faq/index.html" type="text/html" title="F.A.Q." />
|
||||
</head>
|
||||
<!--990301 slightly modified version of the GCC contribute.html file-->
|
||||
<!-- #include virtual="/include/header-subpages.html"-->
|
||||
<body>
|
||||
<h2>How to contribute</h2>
|
||||
<p> The Standard C++ Library v3, follows an open development
|
||||
model. Active contributors are assigned maintainer-ship
|
||||
responsibility, and given write access to the SVN repository. First
|
||||
time contributors should follow this procedure:
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h4>ONE : read the documentation</h4>
|
||||
|
||||
<ul>
|
||||
<li> Get and read the relevant sections of the C++ language
|
||||
specification. Copies of the full ISO 14882 standard are available on
|
||||
line via the ISO mirror site for committee members. Non-members, or
|
||||
those who have not paid for the privilege of sitting on the committee
|
||||
and sustained their two meeting commitment for voting rights, may get
|
||||
a copy of the standard from their respective national standards
|
||||
organization. In the USA, this national standards organization is ANSI
|
||||
and their web-site is right
|
||||
|
||||
<a href="http://www.ansi.org">here.</a>
|
||||
(And if you've already registered with them, clicking this link will take you to directly to the place where you can
|
||||
<a href="http://webstore.ansi.org/ansidocstore/product.asp?sku=ISO%2FIEC+14882%3A2003">buy the standard on-line.)</a>
|
||||
</li>
|
||||
|
||||
<li> The library working group bugs, and known defects, can be obtained here:
|
||||
<a href="http://www.open-std.org/jtc1/sc22/wg21/">http://www.open-std.org/jtc1/sc22/wg21 </a>
|
||||
</li>
|
||||
|
||||
<li> The newsgroup dedicated to standardization issues is comp.std.c++: this FAQ for this group is quite useful and can be found <a href="http://www.jamesd.demon.co.uk/csc/faq.html"> here </a>.
|
||||
</li>
|
||||
|
||||
<li> Peruse the <a href="http://www.gnu.org/prep/standards_toc.html">GNU Coding Standards</a>, and chuckle when you hit the part about "Using Languages Other Than C."
|
||||
</li>
|
||||
|
||||
<li> Be familiar with the extensions that preceded these general GNU rules. These style issues for libstdc++ can be found in the file C++STYLE, located in the root level of the distribution, or <a href="C++STYLE"> here. </a>
|
||||
</li>
|
||||
|
||||
<li> And last but certainly not least, read the library-specific information found <a href="../documentation.html"> here.</a>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
|
||||
<hr />
|
||||
<h4>TWO : copyright assignment</h4>
|
||||
<p>
|
||||
Small changes can be accepted without a copyright assignment form on
|
||||
file. New code and additions to the library need completed copyright
|
||||
assignment form on file at the FSF. Note: your employer may be required
|
||||
to fill out appropriate disclaimer forms as well.
|
||||
</p>
|
||||
|
||||
<p> Historically, the libstdc++ assignment form added the following question:
|
||||
</p>
|
||||
|
||||
<code>[Which Belgian comic book character is better, Tintin or
|
||||
Asterix, and why?]</code>
|
||||
|
||||
<p>
|
||||
While not strictly necessary, humoring the maintainers and answering
|
||||
this question would be appreciated.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For more information about getting a copyright assignment, please see
|
||||
<a href="http://www.gnu.org/prep/maintain/html_node/Legal-Matters.html">Legal
|
||||
Matters</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Please contact <a href="mailto:bkoz+assign@redhat.com">Benjamin
|
||||
Kosnik</a> if you are confused about the assignment or have general
|
||||
licensing questions. When requesting an assignment form from <a
|
||||
href="mailto:assign@gnu.org">assign@gnu.org</a>, please cc
|
||||
the above libstdc++ maintainer so that progress can be monitored.
|
||||
</p>
|
||||
|
||||
|
||||
<hr />
|
||||
<h4>THREE : submitting patches</h4>
|
||||
|
||||
<p>
|
||||
Every patch must have several pieces of information before it can be
|
||||
properly evaluated. Ideally (and to ensure the fastest possible
|
||||
response from the maintainers) it would have all of these pieces:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li> A description of the bug and how your patch fixes this bug. For
|
||||
new features a description of the feature and your implementation. </li>
|
||||
|
||||
<li> A ChangeLog entry as plain text; see the various ChangeLog files
|
||||
for format and content. If using you are using emacs as your editor,
|
||||
simply position the insertion point at the beginning of your change
|
||||
and hit CX-4a to bring up the appropriate ChangeLog
|
||||
entry. See--magic! Similar functionality also exists for vi. </li>
|
||||
|
||||
<li> A testsuite submission or sample program that will easily and
|
||||
simply show the existing error or test new functionality. </li>
|
||||
|
||||
<li> The patch itself. If you are accessing the SVN repository
|
||||
use "svn update; svn diff NEW"; else, use "diff -cp OLD NEW"
|
||||
... If your version of diff does not support these options, then
|
||||
get the latest version of GNU diff. The <a
|
||||
href="http://gcc.gnu.org/wiki/SvnTricks">SVN Tricks</a> wiki page
|
||||
has information on customising the output of <code>svn diff</code>.</li>
|
||||
|
||||
<li> When you have all these pieces, bundle them up in a mail message
|
||||
and send it to libstdc++@gcc.gnu.org. All patches and related
|
||||
discussion should be sent to the libstdc++ mailing list. </li>
|
||||
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,737 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta name="AUTHOR" content="pme@gcc.gnu.org (Phil Edwards), Benjamin Kosnik, Felix Natter" />
|
||||
<meta name="KEYWORDS" content="HOWTO, libstdc++, gcc, g++, libg++, STL" />
|
||||
<meta name="DESCRIPTION" content="HOWTO for libstdc++ chapter 17." />
|
||||
<meta name="GENERATOR" content="vi and eight fingers" />
|
||||
<title>libstdc++ HOWTO: Chapter 17: Library Introduction</title>
|
||||
<link rel="StyleSheet" href="../lib3styles.css" type="text/css" />
|
||||
<link rel="Start" href="../documentation.html" type="text/html"
|
||||
title="GNU C++ Standard Library" />
|
||||
<link rel="Next" href="../18_support/howto.html" type="text/html"
|
||||
title="Library Support" />
|
||||
<link rel="Copyright" href="license.html" type="text/html" />
|
||||
<link rel="Help" href="../faq/index.html" type="text/html" title="F.A.Q." />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 class="centered"><a name="top">Chapter 17: Library Introduction</a></h1>
|
||||
|
||||
<p>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 <em>GNU implementation of</em> the ISO Standard C++ Library.
|
||||
</p>
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
<hr />
|
||||
<h1>Contents</h1>
|
||||
<ul>
|
||||
<li><a href="#2.0">Header Files</a></li>
|
||||
<li><a href="#3.0">Namespaces</a></li>
|
||||
<li><a href="#6">Macros</a></li>
|
||||
<li><a href="#5">Implementation specific behavior</a></li>
|
||||
<li><a href="#7">Multithreading</a></li>
|
||||
</ul>
|
||||
|
||||
<hr />
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<h2><a name="2.0">Header Files</a></h2>
|
||||
<p>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 <code>#include</code>'s a header, the
|
||||
contents of that header become
|
||||
available, no matter how.
|
||||
</p>
|
||||
|
||||
<p>That said, in practice files are used.</p>
|
||||
|
||||
<p> 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).</p>
|
||||
|
||||
<p>Two dialects of standard headers are supported, corresponding to
|
||||
the 1998 standard as updated for 2003, and the draft of the upcoming
|
||||
200x standard.
|
||||
</p>
|
||||
|
||||
<p>C++98/03 include files. These are available in the default compilation mode, ie <code>-std=c++98</code> or <code>-std=gnu++98</code>.
|
||||
</p>
|
||||
|
||||
<center><table border="1"><caption>C++98 Library Headers</caption>
|
||||
<tr><td><algorithm></td><td><iomanip></td><td><list></td><td><ostream></td><td><streambuf></td></tr>
|
||||
<tr><td><bitset></td><td><ios></td><td><locale></td><td><queue></td><td><string></td></tr>
|
||||
<tr><td><complex></td><td><iosfwd></td><td><map></td><td><set></td><td><typeinfo></td></tr>
|
||||
<tr><td><deque></td><td><iostream></td><td><memory></td><td><sstream></td><td><utility></td></tr>
|
||||
<tr><td><exception></td><td><istream></td><td><new></td><td><stack></td><td><valarray></td></tr>
|
||||
<tr><td><fstream></td><td><iterator></td><td><numeric></td><td><stdexcept></td><td><vector></td></tr>
|
||||
<tr><td><functional></td><td><limits></td></tr>
|
||||
</table></center>
|
||||
|
||||
<p></p>
|
||||
|
||||
<center><table border="1"><caption>C++98 Headers for C Library Facilities</caption>
|
||||
<tr><td><cassert></td><td><ciso646></td><td><csetjmp></td><td><cstdio></td><td><ctime></td></tr>
|
||||
<tr><td><cctype></td><td><climits></td><td><csignal></td><td><cstdlib></td><td><cwchar></td></tr>
|
||||
<tr><td><cerrno></td><td><clocale></td><td><cstdarg></td><td><cstring></td><td><cwctype></td></tr>
|
||||
<tr><td><cfloat></td><td><cmath></td><td><cstddef></td></tr>
|
||||
</table></center>
|
||||
|
||||
<p>C++0x include files. These are only available in C++0x compilation mode, ie <code>-std=c++0x</code> or <code>-std=gnu++0x</code>.
|
||||
</p>
|
||||
|
||||
<center><table border="1"><caption>C++0x Library Headers</caption>
|
||||
<tr><td><algorithm></td><td><iomanip></td><td><locale></td><td><regex></td><td><tuple></td></tr>
|
||||
<tr><td><array></td><td><ios></td><td><map></td><td><set></td><td><typeinfo></td></tr>
|
||||
<tr><td><bitset></td><td><iosfwd></td><td><memory></td><td><sstream></td><td><type_traits></td></tr>
|
||||
<tr><td><complex></td><td><iostream></td><td><new></td><td><stack></td><td><unordered_map></td></tr>
|
||||
<tr><td><deque></td><td><istream></td><td><numeric></td><td><stdexcept></td><td><unordered_set></td></tr>
|
||||
<tr><td><exception></td><td><iterator></td><td><ostream></td><td><streambuf></td><td><utility></td></tr>
|
||||
<tr><td><fstream></td><td><limits></td><td><queue></td><td><string></td><td><valarray></td></tr>
|
||||
<tr><td><functional></td><td><list></td><td><random></td><td><system_error></td><td><vector></td></tr>
|
||||
</table></center>
|
||||
|
||||
<p></p>
|
||||
|
||||
<center><table border="1"><caption>C++0x Headers for C Library Facilities</caption>
|
||||
<tr><td><cassert></td><td><cfloat></td><td><cmath></td><td><cstddef></td><td><ctgmath></td></tr>
|
||||
<tr><td><ccomplex></td><td><cinttypes></td><td><csetjmp></td><td><cstdint></td><td><ctime></td></tr>
|
||||
<tr><td><cctype></td><td><ciso646></td><td><csignal></td><td><cstdio></td><td><cuchar></td></tr>
|
||||
<tr><td><cerrno></td><td><climits></td><td><cstdarg></td><td><cstdlib></td><td><cwchar></td></tr>
|
||||
<tr><td><cfenv></td><td><clocale></td><td><cstdbool></td><td><cstring></td><td><cwctype></td></tr>
|
||||
</table></center>
|
||||
|
||||
|
||||
<p>In addition, TR1 includes as:
|
||||
</p>
|
||||
|
||||
<center><table border="1"><caption>TR1 Library Headers</caption>
|
||||
<tr><td><tr1/array></td><td><tr1/memory></td><td><tr1/regex></td><td><tr1/type_traits></td><td><tr1/unordered_set></td></tr>
|
||||
<tr><td><tr1/complex></td><td><tr1/random></td><td><tr1/tuple></td><td><tr1/unordered_map></td><td><tr1/utility></td></tr>
|
||||
<tr><td><tr1/functional></td></tr>
|
||||
</table></center>
|
||||
|
||||
<p></p>
|
||||
|
||||
<center><table border="1"><caption>TR1 Headers for C Library Facilities</caption>
|
||||
<tr><td><tr1/cmath></td><td><tr1/cfloat></td><td><tr1/cstdarg></td><td><tr1/cstdio></td><td><tr1/ctime></td></tr>
|
||||
<tr><td><tr1/ccomplex></td><td><tr1/cinttypes></td><td><tr1/cstdbool></td><td><tr1/cstdlib></td><td><tr1/cwchar></td></tr>
|
||||
<tr><td><tr1/cfenv></td><td><tr1/climits></td><td><tr1/cstdint></td><td><tr1/ctgmath></td><td><tr1/cwctype></td></tr>
|
||||
</table></center>
|
||||
|
||||
<p>Also included are files for the C++ ABI interface:
|
||||
</p>
|
||||
<center><table border="1"><caption>C++ ABI Headers</caption>
|
||||
<tr><td><cxxabi.h></td><td><cxxabi_forced.h></td></tr>
|
||||
</table></center>
|
||||
|
||||
<p>And a large variety of extensions.
|
||||
</p>
|
||||
|
||||
<center><table border="1"><caption>Extension Headers</caption>
|
||||
<tr><td><ext/algorithm></td><td><ext/debug_allocator.h></td><td><ext/mt_allocator.h></td><td><ext/pod_char_traits.h></td><td><ext/stdio_sync_filebuf.h></td></tr>
|
||||
<tr><td><ext/array_allocator.h></td><td><ext/enc_filebuf.h></td><td><ext/new_allocator.h></td><td><ext/pool_allocator.h></td><td><ext/throw_allocator.h></td></tr>
|
||||
<tr><td><ext/atomicity.h></td><td><ext/functional></td><td><ext/numeric></td><td><ext/rb_tree></td><td><ext/typelist.h></td></tr>
|
||||
<tr><td><ext/bitmap_allocator.h></td><td><ext/iterator></td><td><ext/numeric_traits.h></td><td><ext/rope></td><td><ext/type_traits.h></td></tr>
|
||||
<tr><td><ext/codecvt_specializations.h></td><td><ext/malloc_allocator.h></td><td><ext/pb_ds/assoc_container.h></td><td><ext/slist></td><td><ext/vstring.h></td></tr>
|
||||
<tr><td><ext/concurrence.h></td><td><ext/memory></td><td><ext/pb_ds/priority_queue.h></td><td><ext/stdio_filebuf.h></td></tr>
|
||||
</table></center>
|
||||
|
||||
<p></p>
|
||||
|
||||
<center><table border="1"><caption>Extension Debug Headers</caption>
|
||||
<tr><td><debug/bitset></td><td><debug/list></td><td><debug/set></td><td><debug/unordered_map></td><td><debug/vector></td></tr>
|
||||
<tr><td><debug/deque></td><td><debug/map></td><td><debug/string></td><td><debug/unordered_set></td></tr>
|
||||
</table></center>
|
||||
|
||||
<p></p>
|
||||
|
||||
<center><table border="1"><caption>Extension Parallel Headers</caption>
|
||||
<tr><td><parallel/algorithm></td><td><parallel/numeric></td></tr>
|
||||
</table></center>
|
||||
|
||||
<hr />
|
||||
<h2><a name="2.1">Recipes for mixing headers</a></h2>
|
||||
|
||||
<p> A few simple rules.
|
||||
</p>
|
||||
|
||||
<p>First, mixing different dialects of the standard headers is not
|
||||
possible. It's an all-or-nothing affair. Thus, code like
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
#include <array>
|
||||
#include <functional>
|
||||
</pre>
|
||||
|
||||
<p>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.
|
||||
</p>
|
||||
|
||||
<p>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 <code>__gnu_cxx::vstring</code>, or to use the
|
||||
debug-mode versions of <code>std::unordered_map</code>, one must use
|
||||
the <code>std=gnu++0x</code> compiler flag. (Or <code>std=c++0x</code>, of course.)
|
||||
</p>
|
||||
|
||||
<p>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:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
#include <tr1/type_traits>
|
||||
#include <type_traits>
|
||||
</pre>
|
||||
|
||||
<p> Several parts of C++0x diverge quite substantially from TR1 predecessors.
|
||||
</p>
|
||||
|
||||
|
||||
<hr />
|
||||
<h2><a name="2.2">The C Headers and <code>namespace std</code></a></h2>
|
||||
<p>
|
||||
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 <code>std::</code> (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.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Usage of C++-style headers is recommended, as then
|
||||
C-linkage names can be disambiguated by explicit qualification, such
|
||||
as by <code>std::abort</code>. 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 <code>std::sin</code> has overloads for all the builtin
|
||||
floating-point types. This means that <code>std::sin</code> can be
|
||||
used uniformly, instead of a combination
|
||||
of <code>std::sinf</code>, <code>std::sin</code>,
|
||||
and <code>std::sinl</code>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="2.3">Precompiled Headers</a></h2>
|
||||
|
||||
<p>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.
|
||||
</p>
|
||||
|
||||
|
||||
<ul>
|
||||
<li>stdc++.h
|
||||
<p>Includes all standard headers. Actual content varies depending on
|
||||
language dialect.
|
||||
</p>
|
||||
</li>
|
||||
|
||||
<li>stdtr1c++.h
|
||||
<p>Includes all of <stdc++.h>, and adds all the TR1 headers.
|
||||
</p>
|
||||
</li>
|
||||
|
||||
<li>extc++.h
|
||||
<p>Includes all of <stdtr1c++.h>, and adds all the Extension headers.
|
||||
</p></li>
|
||||
</ul>
|
||||
|
||||
<p>How to construct a .gch file from one of these base header files.</p>
|
||||
|
||||
<p>First, find the include directory for the compiler. One way to do
|
||||
this is:</p>
|
||||
|
||||
<pre>
|
||||
g++ -v hello.cc
|
||||
|
||||
#include <...> search starts here:
|
||||
/mnt/share/bld/H-x86-gcc.20071201/include/c++/4.3.0
|
||||
...
|
||||
End of search list.
|
||||
</pre>
|
||||
|
||||
|
||||
<p>Then, create a precompiled header file with the same flags that
|
||||
will be used to compile other projects.</p>
|
||||
|
||||
<pre>
|
||||
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
|
||||
</pre>
|
||||
|
||||
<p>The resulting file will be quite large: the current size is around
|
||||
thirty megabytes. </p>
|
||||
|
||||
<p>How to use the resulting file.</p>
|
||||
|
||||
<pre>
|
||||
g++ -I. -include stdc++.h -H -g -O2 hello.cc
|
||||
</pre>
|
||||
|
||||
<p>Verification that the PCH file is being used is easy:</p>
|
||||
|
||||
<pre>
|
||||
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
|
||||
</pre>
|
||||
|
||||
<p>The exclamation point to the left of the <code>stdc++.h.gch</code> listing means that the generated PCH file was used, and thus the </p>
|
||||
<p></p>
|
||||
|
||||
<p> Detailed information about creating precompiled header files can be found in the GCC <a href="http://gcc.gnu.org/onlinedocs/gcc/Precompiled-Headers.html">documentation</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<hr />
|
||||
<h2><a name="3.0">Namespaces</a></h2>
|
||||
|
||||
|
||||
<p> There are three main namespaces.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>std
|
||||
<p>The ISO C++ standards specify that "all library entities are defined
|
||||
within namespace std." This includes namepaces nested
|
||||
within <code>namespace std</code>, such as <code>namespace
|
||||
std::tr1</code>.
|
||||
</p>
|
||||
</li>
|
||||
<li>abi
|
||||
<p>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.
|
||||
</p>
|
||||
</li>
|
||||
|
||||
<li>__gnu_
|
||||
<p>Indicating one of several GNU extensions. Choices
|
||||
include <code>__gnu_cxx</code>, <code>__gnu_debug</code>, <code>__gnu_parallel</code>,
|
||||
and <code>__gnu_pbds</code>.
|
||||
</p></li>
|
||||
</ul>
|
||||
|
||||
<p> A complete list of implementation namespaces (including namespace contents) is available in the generated source <a href="http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/namespaces.html">documentation</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<hr />
|
||||
<h2><a name="3.1">Namespace <code>std::</code></a></h2>
|
||||
|
||||
<p>
|
||||
One standard requirement is that the library components are defined
|
||||
in <code>namespace std::</code>. Thus, in order to use these types or
|
||||
functions, one must do one of two things:
|
||||
</p>
|
||||
|
||||
<div class="itemizedlist"><ul type="disc"> <li><p>put a kind of
|
||||
<span class="emphasis"><i>using-declaration</i></span> in your source
|
||||
(either <code>using namespace std;</code> or i.e. <code>using
|
||||
std::string;</code>) This approach works well for individual source files, but
|
||||
should not be used in a global context, like header files.
|
||||
</p></li> <li><p>use a <span class="emphasis"><i>fully
|
||||
qualified name</i></span> for each library symbol
|
||||
(i.e. <code>std::string</code>, <code>std::cout</code>) Always can be
|
||||
used, and usually enhanced, by strategic use of typedefs. (In the
|
||||
cases where the qualified verbiage becomes unwieldy.)
|
||||
</p></li>
|
||||
</ul></div>
|
||||
|
||||
<hr />
|
||||
<h2><a name="3.2">Using namespace composition</a></h2>
|
||||
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
|
||||
<p>For instance, consider a project that defines most of its classes in <code>namespace gtk</code>. It is possible to
|
||||
adapt <code>namespace gtk</code> to <code>namespace std</code> by using a C++-feature called
|
||||
<span class="emphasis"><i>namespace composition</i></span>. This is what happens if
|
||||
a <span class="emphasis"><i>using</i></span>-declaration is put into a
|
||||
namespace-definition: the imported symbol(s) gets imported into the
|
||||
currently active namespace(s). For example:
|
||||
</p>
|
||||
<pre class="programlisting">
|
||||
namespace gtk
|
||||
{
|
||||
using std::string;
|
||||
using std::tr1::array;
|
||||
|
||||
class Window { ... };
|
||||
}
|
||||
</pre>
|
||||
<p>
|
||||
In this example, <code>std::string</code> gets imported into
|
||||
<code>namespace gtk</code>. The result is that use of
|
||||
<code>std::string</code> inside namespace gtk can just use <code>string</code>, without the explicit qualification.
|
||||
As an added bonus,
|
||||
<code>std::string</code> does not get imported into
|
||||
the global namespace. Additionally, a more elaborate arrangement can be made for backwards compatibility and portability, whereby the
|
||||
<code>using</code>-declarations can wrapped in macros that
|
||||
are set based on autoconf-tests to either "" or i.e. <code>using
|
||||
std::string;</code> (depending on whether the system has
|
||||
libstdc++ in <code>std::</code> or not). (ideas from
|
||||
<tt><<a href="mailto:llewelly@dbritsch.dsl.xmission.com">llewelly@dbritsch.dsl.xmission.com</a>></tt>, Karl Nelson
|
||||
<tt><<a href="mailto:kenelson@ece.ucdavis.edu">kenelson@ece.ucdavis.edu</a>></tt>)
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="6">Macros for libstdc++</a></h2>
|
||||
|
||||
<p>All pre-processor switches and configurations are all gathered
|
||||
in the file <code>c++config.h</code>, 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. <strong>These macros cannot be
|
||||
redefined</strong>. 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.
|
||||
</p>
|
||||
|
||||
<p>All library macros begin with <code>_GLIBCXX_</code> (except for
|
||||
versions 3.1.x to 3.3.x, which use <code>_GLIBCPP_</code>).
|
||||
</p>
|
||||
|
||||
<p>Below is the macro which users may check for library version
|
||||
information. </p>
|
||||
|
||||
<dl>
|
||||
<dt><code>__GLIBCXX__</code></dt> <dd>The current version of
|
||||
libstdc++ in compressed ISO date format, form of an unsigned
|
||||
long. For details on the value of this particular macro for a
|
||||
particular release, please consult this <a href="abi.html">
|
||||
document</a>.</dd> </dl>
|
||||
|
||||
<p>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.</p>
|
||||
|
||||
<p>"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 <a href="../configopts.html">here</a>), with the
|
||||
various --enable/--disable choices being translated to
|
||||
#define/#undef).
|
||||
</p>
|
||||
|
||||
<p> "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 <em>headers</em> may see different code
|
||||
paths, but the <em>libraries</em> 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.
|
||||
</p>
|
||||
|
||||
<dl>
|
||||
<dt><code>_GLIBCXX_DEPRECATED</code></dt>
|
||||
<dd>Defined by default. Not configurable. ABI-changing. Turning this off
|
||||
removes older ARM-style iostreams code, and other anachronisms
|
||||
from the API. This macro is dependent on the version of the
|
||||
standard being tracked, and as a result may give different results for
|
||||
<code>-std=c++98</code> and <code>-std=c++0x</code>. 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. </dd>
|
||||
|
||||
<dt><code>_GLIBCXX_FORCE_NEW</code></dt> <dd>Undefined by
|
||||
default. When defined, memory allocation and allocators controlled
|
||||
by libstdc++ call operator new/delete without caching and
|
||||
pooling. Configurable via
|
||||
<code>--enable-libstdcxx-allocator</code>. ABI-changing.
|
||||
</dd>
|
||||
|
||||
|
||||
<dt><code>_GLIBCXX_CONCEPT_CHECKS</code></dt> <dd>Undefined by
|
||||
default. Configurable via <code>--enable-concept-checks</code>.
|
||||
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 <a
|
||||
href="../19_diagnostics/howto.html#3">here</a>.</dd>
|
||||
|
||||
<dt><code>_GLIBCXX_DEBUG</code></dt>
|
||||
<dd>Undefined by default. When defined, compiles
|
||||
user code using the <a href="../ext/debug.html#safe">libstdc++ debug
|
||||
mode</a>.
|
||||
</dd>
|
||||
<dt><code>_GLIBCXX_DEBUG_PEDANTIC</code></dt>
|
||||
<dd>Undefined by default. When defined while
|
||||
compiling with the <a href="../ext/debug.html#safe">libstdc++ debug
|
||||
mode</a>, makes the debug mode extremely picky by making the use
|
||||
of libstdc++ extensions and libstdc++-specific behavior into
|
||||
errors.
|
||||
</dd>
|
||||
<dt><code>_GLIBCXX_PARALLEL</code></dt>
|
||||
<dd>Undefined by default. When defined, compiles
|
||||
user code using the <a href="../ext/parallel_mode.html">libstdc++ parallel
|
||||
mode</a>.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<hr />
|
||||
<h2><a name="7">The Standard C++ library and multithreading</a></h2>
|
||||
<p>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.
|
||||
</p>
|
||||
<p>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.
|
||||
</p>
|
||||
<p>All normal disclaimers aside, multithreaded C++ application are
|
||||
only supported when libstdc++ and all user code was built with
|
||||
compilers which report (via <code> gcc/g++ -v </code>) the same thread
|
||||
model and that model is not <em>single</em>. 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
|
||||
<em>single</em> 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.)
|
||||
</p>
|
||||
<p>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).
|
||||
</p>
|
||||
<p>See <a href="../faq/index.html#5_6">FAQ</a> (general overview), <a
|
||||
href="../23_containers/howto.html#3">23</a> (containers), and <a
|
||||
href="../27_io/howto.html#9">27</a> (I/O) for more information.
|
||||
</p>
|
||||
<p>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 <em>fast</em> 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 <a
|
||||
href="http://www.sgi.com/tech/stl/thread_safety.html">same
|
||||
definition that SGI</a> 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.
|
||||
</p>
|
||||
<p>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.
|
||||
</p>
|
||||
<ul>
|
||||
<li>Our threading expert Loren gives a breakdown of
|
||||
<a href="http://gcc.gnu.org/ml/libstdc++/2001-10/msg00024.html">the
|
||||
six situations involving threads</a> for the 3.0 release series.</li>
|
||||
<li><a href="http://gcc.gnu.org/ml/libstdc++/2001-05/msg00384.html">
|
||||
This message</a> inspired a recent updating of issues with threading
|
||||
and the SGI STL library. It also contains some example
|
||||
POSIX-multithreaded STL code.</li>
|
||||
</ul>
|
||||
<p> (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.)
|
||||
</p>
|
||||
<p>This section will be updated as new and interesting issues come
|
||||
to light.
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="5">Behavior specific to libstdc++</a></h2>
|
||||
<p>The ISO standard defines the following phrase:
|
||||
</p>
|
||||
<blockquote><dl>
|
||||
<dt><code>[1.3.5] implementation-defined behavior</code></dt>
|
||||
<dd>behavior, for a well-formed program construct and correct data, that
|
||||
depends on the implementation <strong>and that each implementation
|
||||
shall document</strong>.
|
||||
</dd>
|
||||
</dl></blockquote>
|
||||
<p>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.
|
||||
</p>
|
||||
<p>For each entry, we give the section number of the standard, when
|
||||
applicable. This list is probably incomplet and inkorrekt.
|
||||
</p>
|
||||
<p><strong>[1.9]/11 #3</strong> If <code>isatty(3)</code> is true, then
|
||||
interactive stream support is implied.
|
||||
</p>
|
||||
<p><strong>[17.4.4.5]</strong> Non-reentrant functions are probably best
|
||||
discussed in the various sections on multithreading (see above).
|
||||
</p>
|
||||
<!-- [17.4.4.8]/3 says any function that doesn't have an exception-spec
|
||||
can throw whatever we want; see also its footnote. Let's list those
|
||||
in the sections where the function itself occurs.
|
||||
-->
|
||||
<p><strong>[18.1]/4</strong> The type of <code>NULL</code> is described
|
||||
<a href="../18_support/howto.html#1">here</a>.
|
||||
</p>
|
||||
<p><strong>[18.3]/8</strong> 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. :-)
|
||||
</p>
|
||||
<p><strong>[18.4.2.1]/5</strong> (bad_alloc),<br />
|
||||
<strong>[18.5.2]/5</strong> (bad_cast),<br />
|
||||
<strong>[18.5.3]/5</strong> (bad_typeid),<br />
|
||||
<strong>[18.6.1]/8</strong> (exception),<br />
|
||||
<strong>[18.6.2.1]/5</strong> (bad_exception): The <code>what()</code>
|
||||
member function of class <code>std::exception</code>, and these other
|
||||
classes publicly derived from it, simply returns the name of the
|
||||
class. But they are the <em>mangled</em> names; you will need to call
|
||||
<code>c++filt</code> and pass the names as command-line parameters to
|
||||
demangle them, or call a
|
||||
<a href="../18_support/howto.html#5">runtime demangler function</a>.
|
||||
(The classes in <code><stdexcept></code> have constructors which
|
||||
require an argument to use later for <code>what()</code> calls, so the
|
||||
problem of <code>what()</code>'s value does not arise in most
|
||||
user-defined exceptions.)
|
||||
</p>
|
||||
<p><strong>[18.5.1]/7</strong> The return value of
|
||||
<code>std::type_info::name()</code> is the mangled type name (see the
|
||||
previous entry for more).
|
||||
</p>
|
||||
<p><strong>[20.1.5]/5</strong> <em>"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."</em> As yet we don't
|
||||
have any allocators which compare non-equal, so we can't describe how
|
||||
they behave.
|
||||
</p>
|
||||
<p><strong>[21.1.3.1]/3,4</strong>,<br />
|
||||
<strong>[21.1.3.2]/2</strong>,<br />
|
||||
<strong>[23.*]'s foo::iterator</strong>,<br />
|
||||
<strong>[27.*]'s foo::*_type</strong>,<br />
|
||||
<strong>others...</strong>
|
||||
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. :-)
|
||||
</p>
|
||||
<p><strong>[21.1.3.1]/5</strong> I don't really know about the mbstate_t
|
||||
stuff... see the <a href="../22_locale/howto.html">chapter 22 notes</a>
|
||||
for what does exist.
|
||||
</p>
|
||||
<p><strong>[22.*]</strong> Anything and everything we have on locale
|
||||
implementation will be described
|
||||
<a href="../22_locale/howto.html">over here</a>.
|
||||
</p>
|
||||
<p><strong>[26.2.8]/9</strong> I have no idea what
|
||||
<code>complex<T></code>'s pow(0,0) returns.
|
||||
</p>
|
||||
<p><strong>[27.4.2.4]/2</strong> Calling
|
||||
<code>std::ios_base::sync_with_stdio</code> after I/O has already been
|
||||
performed on the standard stream objects will
|
||||
flush the buffers, and <!-- this line might go away -->
|
||||
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!
|
||||
</p>
|
||||
<p><strong>[27.6.1.1.2]</strong>,<br />
|
||||
<strong>[27.6.2.3]</strong> The I/O sentry ctor and dtor can perform
|
||||
additional work than the minimum required. We are not currently taking
|
||||
advantage of this yet.
|
||||
</p>
|
||||
<p><strong>[27.7.1.3]/16</strong>,<br />
|
||||
<strong>[27.8.1.4]/10</strong>
|
||||
The effects of <code>pubsetbuf/setbuf</code> are described
|
||||
<a href="../27_io/howto.html#2">in this chapter</a>.
|
||||
</p>
|
||||
<p><strong>[27.8.1.4]/16</strong> Calling <code>fstream::sync</code> when
|
||||
a get area exists will... whatever <code>fflush()</code> does, I think.
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<!--
|
||||
<dt><code></code></dt>
|
||||
<dd>
|
||||
</dd>
|
||||
-->
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<hr />
|
||||
<p class="fineprint"><em>
|
||||
See <a href="license.html">license.html</a> for copying conditions.
|
||||
Comments and suggestions are welcome, and may be sent to
|
||||
<a href="mailto:libstdc++@gcc.gnu.org">the libstdc++ mailing list</a>.
|
||||
</em></p>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
@ -1,119 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta name="AUTHOR" content="pme@gcc.gnu.org (Phil Edwards)" />
|
||||
<meta name="KEYWORDS" content="libstdc++, license, licence" />
|
||||
<meta name="DESCRIPTION" content="Copying restrictions for libstdc++." />
|
||||
<meta name="GENERATOR" content="vi and eight fingers" />
|
||||
<title>libstdc++ copying</title>
|
||||
<link rel="StyleSheet" href="../lib3styles.css" type="text/css" />
|
||||
<link rel="Start" rev="Copyright" href="../documentation.html" type="text/html"
|
||||
title="GNU C++ Standard Library" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 class="centered"><a name="top">Licenses for the Library</a></h1>
|
||||
|
||||
<p>There are two licenses affecting GNU libstdc++: one for the code, and
|
||||
one for the documentation. Here we will describe both of them, and try
|
||||
to answer some of the widespread questions. If you have more questions,
|
||||
ask the FSF or the
|
||||
<a href="http://gcc.gnu.org/lists.html">gcc mailing list</a>; the person
|
||||
writing this page is a programmer, not a lawyer.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
|
||||
<h2>The Code: Runtime GPL</h2>
|
||||
|
||||
<p>The source code of libstdc++ is distributed under version 2 of the
|
||||
<a href="COPYING" type="text/plain">GNU General Public License</a>, with the so-called
|
||||
"runtime exception," as follows (or see any header or
|
||||
implementation file):
|
||||
</p>
|
||||
<pre>
|
||||
As a special exception, you may use this file as part of a free software
|
||||
library without restriction. Specifically, if other files instantiate
|
||||
templates or use macros or inline functions from this file, or you compile
|
||||
this file and link it with other files to produce an executable, this
|
||||
file does not by itself cause the resulting executable to be covered by
|
||||
the GNU General Public License. This exception does not however
|
||||
invalidate any other reasons why the executable file might be covered by
|
||||
the GNU General Public License.
|
||||
</pre>
|
||||
|
||||
<p>Hopefully that text is self-explanatory. If it isn't, you need to speak
|
||||
to your lawyer, or the Free Software Foundation.
|
||||
</p>
|
||||
|
||||
<!-- Most of the Q&A's are based on, paraphrased from, and outright stolen
|
||||
from this thread:
|
||||
http://gcc.gnu.org/ml/libstdc++/2000-q2/subjects.html#00050
|
||||
-->
|
||||
<p><strong>Q: So any program which uses libstdc++ falls under the GPL?</strong>
|
||||
<br />A: <strong>No.</strong> The special exception permits use of the
|
||||
library in proprietary applications.
|
||||
</p>
|
||||
|
||||
<p><strong>Q: How is that different from the GNU {Lesser,Library}
|
||||
GPL?</strong>
|
||||
<!-- Quoting Jason Merrill from the thread above: -->
|
||||
<br />A: The LGPL requires that users be able to replace the LGPL code with a
|
||||
modified version; this is trivial if the library in question is a C
|
||||
shared library. But there's no way to make that work with C++, where
|
||||
much of the library consists of inline functions and templates, which
|
||||
are expanded inside the code that uses the library. So to allow people
|
||||
to replace the library code, someone using the library would have to
|
||||
distribute their own source, rendering the LGPL equivalent to the GPL.
|
||||
</p>
|
||||
|
||||
<p><strong>Q: I see. So, what restrictions <em>are</em> there on
|
||||
programs that use the library?</strong>
|
||||
<br />A: None. We encourage such programs to be released as open source,
|
||||
but we won't punish you or sue you if you choose otherwise.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
|
||||
<h2>The Docs: GPL, FDL</h2>
|
||||
|
||||
<p>The documentation shipped with the library and made available over the
|
||||
web, excluding the pages generated from source comments, are copyrighted
|
||||
by the Free Software Foundation, and placed under
|
||||
the <a href="COPYING.DOC" type="text/plain">GNU Free Documentation License version 1.1</a>.
|
||||
There are no Front-Cover Texts, no Back-Cover Texts, and
|
||||
<!-- as far as I know -->
|
||||
no Invariant Sections.
|
||||
</p>
|
||||
|
||||
<p> For documentation generated by doxygen or other automated tools
|
||||
via processing source code comments and markup, the original source
|
||||
code license applies to the generated files. Thus, the doxygen
|
||||
documents are licensed GPL.
|
||||
</p>
|
||||
|
||||
<p>If you plan on making copies of the documentation, please let us know.
|
||||
We can probably offer suggestions.
|
||||
</p>
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<hr />
|
||||
<p class="fineprint"><em>
|
||||
Comments and suggestions about this page are welcome, and may be sent to
|
||||
<a href="mailto:libstdc++@gcc.gnu.org">the libstdc++ mailing list</a>.
|
||||
Comments or questions about the licenses themselves are also welcome, and
|
||||
should be directed to the GCC list as descibed above.
|
||||
</em></p>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
@ -1,992 +0,0 @@
|
|||
<html lang="en">
|
||||
<head>
|
||||
<title>Porting libstdc++</title>
|
||||
<meta http-equiv="Content-Type" content="text/html">
|
||||
<meta name="description" content="Porting libstdc++">
|
||||
<meta name="generator" content="makeinfo 4.6">
|
||||
<!--
|
||||
Copyright © 2000, 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
|
||||
|
||||
<p>Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.2 or
|
||||
any later version published by the Free Software Foundation; with the
|
||||
Invariant Sections being "GNU General Public License", the Front-Cover
|
||||
texts being (a) (see below), and with the Back-Cover Texts being (b)
|
||||
(see below). A copy of the license is included in the section entitled
|
||||
"GNU Free Documentation License".
|
||||
|
||||
<p>(a) The FSF's Front-Cover Text is:
|
||||
|
||||
<p>A GNU Manual
|
||||
|
||||
<p>(b) The FSF's Back-Cover Text is:
|
||||
|
||||
<p>You have freedom to copy and modify this GNU Manual, like GNU
|
||||
software. Copies published by the Free Software Foundation raise
|
||||
funds for GNU development.-->
|
||||
<meta http-equiv="Content-Style-Type" content="text/css">
|
||||
<style type="text/css"><!--
|
||||
pre.display { font-family:inherit }
|
||||
pre.format { font-family:inherit }
|
||||
pre.smalldisplay { font-family:inherit; font-size:smaller }
|
||||
pre.smallformat { font-family:inherit; font-size:smaller }
|
||||
pre.smallexample { font-size:smaller }
|
||||
pre.smalllisp { font-size:smaller }
|
||||
--></style>
|
||||
</head>
|
||||
<body>
|
||||
<h1 class="settitle">Porting libstdc++</h1>
|
||||
<div class="node">
|
||||
<p><hr>
|
||||
Node: <a name="Top">Top</a>,
|
||||
Next: <a rel="next" accesskey="n" href="#Operating%20system">Operating system</a>,
|
||||
Up: <a rel="up" accesskey="u" href="#dir">(dir)</a>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<h2 class="unnumbered">Porting libstdc++</h2>
|
||||
|
||||
<p>This document explains how to port libstdc++ (the GNU C++ library) to
|
||||
a new target.
|
||||
|
||||
<p>In order to make the GNU C++ library (libstdc++) work with a new
|
||||
target, you must edit some configuration files and provide some new
|
||||
header files. Unless this is done, libstdc++ will use generic
|
||||
settings which may not be correct for your target; even if they are
|
||||
correct, they will likely be inefficient.
|
||||
|
||||
<p>Before you get started, make sure that you have a working C library on
|
||||
your target. The C library need not precisely comply with any
|
||||
particular standard, but should generally conform to the requirements
|
||||
imposed by the ANSI/ISO standard.
|
||||
|
||||
<p>In addition, you should try to verify that the C++ compiler generally
|
||||
works. It is difficult to test the C++ compiler without a working
|
||||
library, but you should at least try some minimal test cases.
|
||||
|
||||
<p>(Note that what we think of as a "target," the library refers to as
|
||||
a "host." The comment at the top of <code>configure.ac</code> explains why.)
|
||||
|
||||
<p>Here are the primary steps required to port the library:
|
||||
|
||||
<ul class="menu">
|
||||
<li><a accesskey="1" href="#Operating%20system">Operating system</a>: Configuring for your operating system.
|
||||
<li><a accesskey="2" href="#CPU">CPU</a>: Configuring for your processor chip.
|
||||
<li><a accesskey="3" href="#Character%20types">Character types</a>: Implementing character classification.
|
||||
<li><a accesskey="4" href="#Thread%20safety">Thread safety</a>: Implementing atomic operations.
|
||||
<li><a accesskey="5" href="#Numeric%20limits">Numeric limits</a>: Implementing numeric limits.
|
||||
<li><a accesskey="6" href="#Libtool">Libtool</a>: Using libtool.
|
||||
<li><a accesskey="7" href="#GNU%20Free%20Documentation%20License">GNU Free Documentation License</a>: How you can copy and share this manual.
|
||||
</ul>
|
||||
|
||||
<div class="node">
|
||||
<p><hr>
|
||||
Node: <a name="Operating%20system">Operating system</a>,
|
||||
Next: <a rel="next" accesskey="n" href="#CPU">CPU</a>,
|
||||
Previous: <a rel="previous" accesskey="p" href="#Top">Top</a>,
|
||||
Up: <a rel="up" accesskey="u" href="#Top">Top</a>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<h2 class="chapter">Operating system</h2>
|
||||
|
||||
<p>If you are porting to a new operating system (as opposed to a new chip
|
||||
using an existing operating system), you will need to create a new
|
||||
directory in the <code>config/os</code> hierarchy. For example, the IRIX
|
||||
configuration files are all in <code>config/os/irix</code>. There is no set
|
||||
way to organize the OS configuration directory. For example,
|
||||
<code>config/os/solaris/solaris-2.6</code> and
|
||||
<code>config/os/solaris/solaris-2.7</code> are used as configuration
|
||||
directories for these two versions of Solaris. On the other hand, both
|
||||
Solaris 2.7 and Solaris 2.8 use the <code>config/os/solaris/solaris-2.7</code>
|
||||
directory. The important information is that there needs to be a
|
||||
directory under <code>config/os</code> to store the files for your operating
|
||||
system.
|
||||
|
||||
<p>You might have to change the <code>configure.host</code> file to ensure that
|
||||
your new directory is activated. Look for the switch statement that sets
|
||||
<code>os_include_dir</code>, and add a pattern to handle your operating system
|
||||
if the default will not suffice. The switch statement switches on only
|
||||
the OS portion of the standard target triplet; e.g., the <code>solaris2.8</code>
|
||||
in <code>sparc-sun-solaris2.8</code>. If the new directory is named after the
|
||||
OS portion of the triplet (the default), then nothing needs to be changed.
|
||||
|
||||
<p>The first file to create in this directory, should be called
|
||||
<code>os_defines.h</code>. This file contains basic macro definitions
|
||||
that are required to allow the C++ library to work with your C library.
|
||||
|
||||
<p>Several libstdc++ source files unconditionally define the macro
|
||||
<code>_POSIX_SOURCE</code>. On many systems, defining this macro causes
|
||||
large portions of the C library header files to be eliminated
|
||||
at preprocessing time. Therefore, you may have to <code>#undef</code> this
|
||||
macro, or define other macros (like <code>_LARGEFILE_SOURCE</code> or
|
||||
<code>__EXTENSIONS__</code>). You won't know what macros to define or
|
||||
undefine at this point; you'll have to try compiling the library and
|
||||
seeing what goes wrong. If you see errors about calling functions
|
||||
that have not been declared, look in your C library headers to see if
|
||||
the functions are declared there, and then figure out what macros you
|
||||
need to define. You will need to add them to the
|
||||
<code>CPLUSPLUS_CPP_SPEC</code> macro in the GCC configuration file for your
|
||||
target. It will not work to simply define these macros in
|
||||
<code>os_defines.h</code>.
|
||||
|
||||
<p>At this time, there are a few libstdc++-specific macros which may be
|
||||
defined:
|
||||
|
||||
<p><code>_GLIBCXX_USE_C99_CHECK</code> may be defined to 1 to check C99
|
||||
function declarations (which are not covered by specialization below)
|
||||
found in system headers against versions found in the library headers
|
||||
derived from the standard.
|
||||
|
||||
<p><code>_GLIBCXX_USE_C99_DYNAMIC</code> may be defined to an expression that
|
||||
yields 0 if and only if the system headers are exposing proper support
|
||||
for C99 functions (which are not covered by specialization below). If
|
||||
defined, it must be 0 while bootstrapping the compiler/rebuilding the
|
||||
library.
|
||||
|
||||
<p><code>_GLIBCXX_USE_C99_LONG_LONG_CHECK</code> may be defined to 1 to check
|
||||
the set of C99 long long function declarations found in system headers
|
||||
against versions found in the library headers derived from the
|
||||
standard.
|
||||
|
||||
<p><code>_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC</code> may be defined to an
|
||||
expression that yields 0 if and only if the system headers are
|
||||
exposing proper support for the set of C99 long long functions. If
|
||||
defined, it must be 0 while bootstrapping the compiler/rebuilding the
|
||||
library.
|
||||
|
||||
<p><code>_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC</code> may be defined to an
|
||||
expression that yields 0 if and only if the system headers
|
||||
are exposing proper support for the related set of macros. If defined,
|
||||
it must be 0 while bootstrapping the compiler/rebuilding the library.
|
||||
|
||||
<p><code>_GLIBCXX_USE_C99_FLOAT_TRANSCENDENTALS_CHECK</code> may be defined
|
||||
to 1 to check the related set of function declarations found in system
|
||||
headers against versions found in the library headers derived from
|
||||
the standard.
|
||||
|
||||
<p><code>_GLIBCXX_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC</code> may be defined
|
||||
to an expression that yields 0 if and only if the system headers
|
||||
are exposing proper support for the related set of functions. If defined,
|
||||
it must be 0 while bootstrapping the compiler/rebuilding the library.
|
||||
|
||||
<p>Finally, you should bracket the entire file in an include-guard, like
|
||||
this:
|
||||
|
||||
<pre class="example"> #ifndef _GLIBCXX_OS_DEFINES
|
||||
#define _GLIBCXX_OS_DEFINES
|
||||
...
|
||||
#endif
|
||||
</pre>
|
||||
|
||||
<p>We recommend copying an existing <code>os_defines.h</code> to use as a
|
||||
starting point.
|
||||
|
||||
<div class="node">
|
||||
<p><hr>
|
||||
Node: <a name="CPU">CPU</a>,
|
||||
Next: <a rel="next" accesskey="n" href="#Character%20types">Character types</a>,
|
||||
Previous: <a rel="previous" accesskey="p" href="#Operating%20system">Operating system</a>,
|
||||
Up: <a rel="up" accesskey="u" href="#Top">Top</a>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<h2 class="chapter">CPU</h2>
|
||||
|
||||
<p>If you are porting to a new chip (as opposed to a new operating system
|
||||
running on an existing chip), you will need to create a new directory in the
|
||||
<code>config/cpu</code> hierarchy. Much like the <a href="#Operating%20system">Operating system</a> setup,
|
||||
there are no strict rules on how to organize the CPU configuration
|
||||
directory, but careful naming choices will allow the configury to find your
|
||||
setup files without explicit help.
|
||||
|
||||
<p>We recommend that for a target triplet <code><CPU>-<vendor>-<OS></code>, you
|
||||
name your configuration directory <code>config/cpu/<CPU></code>. If you do this,
|
||||
the configury will find the directory by itself. Otherwise you will need to
|
||||
edit the <code>configure.host</code> file and, in the switch statement that sets
|
||||
<code>cpu_include_dir</code>, add a pattern to handle your chip.
|
||||
|
||||
<p>Note that some chip families share a single configuration directory, for
|
||||
example, <code>alpha</code>, <code>alphaev5</code>, and <code>alphaev6</code> all use the
|
||||
<code>config/cpu/alpha</code> directory, and there is an entry in the
|
||||
<code>configure.host</code> switch statement to handle this.
|
||||
|
||||
<p>The <code>cpu_include_dir</code> sets default locations for the files controlling
|
||||
<a href="#Thread%20safety">Thread safety</a> and <a href="#Numeric%20limits">Numeric limits</a>, if the defaults are not
|
||||
appropriate for your chip.
|
||||
|
||||
<div class="node">
|
||||
<p><hr>
|
||||
Node: <a name="Character%20types">Character types</a>,
|
||||
Next: <a rel="next" accesskey="n" href="#Thread%20safety">Thread safety</a>,
|
||||
Previous: <a rel="previous" accesskey="p" href="#CPU">CPU</a>,
|
||||
Up: <a rel="up" accesskey="u" href="#Top">Top</a>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<h2 class="chapter">Character types</h2>
|
||||
|
||||
<p>The library requires that you provide three header files to implement
|
||||
character classification, analogous to that provided by the C libraries
|
||||
<code><ctype.h></code> header. You can model these on the files provided in
|
||||
<code>config/os/generic</code>. However, these files will almost
|
||||
certainly need some modification.
|
||||
|
||||
<p>The first file to write is <code>ctype_base.h</code>. This file provides
|
||||
some very basic information about character classification. The libstdc++
|
||||
library assumes that your C library implements <code><ctype.h></code> by using
|
||||
a table (indexed by character code) containing integers, where each of
|
||||
these integers is a bit-mask indicating whether the character is
|
||||
upper-case, lower-case, alphabetic, etc. The <code>ctype_base.h</code>
|
||||
file gives the type of the integer, and the values of the various bit
|
||||
masks. You will have to peer at your own <code><ctype.h></code> to figure out
|
||||
how to define the values required by this file.
|
||||
|
||||
<p>The <code>ctype_base.h</code> header file does not need include guards.
|
||||
It should contain a single <code>struct</code> definition called
|
||||
<code>ctype_base</code>. This <code>struct</code> should contain two type
|
||||
declarations, and one enumeration declaration, like this example, taken
|
||||
from the IRIX configuration:
|
||||
|
||||
<pre class="example"> struct ctype_base
|
||||
{
|
||||
typedef unsigned int mask;
|
||||
typedef int* __to_type;
|
||||
|
||||
enum
|
||||
{
|
||||
space = _ISspace,
|
||||
print = _ISprint,
|
||||
cntrl = _IScntrl,
|
||||
upper = _ISupper,
|
||||
lower = _ISlower,
|
||||
alpha = _ISalpha,
|
||||
digit = _ISdigit,
|
||||
punct = _ISpunct,
|
||||
xdigit = _ISxdigit,
|
||||
alnum = _ISalnum,
|
||||
graph = _ISgraph
|
||||
};
|
||||
};
|
||||
</pre>
|
||||
|
||||
<p>The <code>mask</code> type is the type of the elements in the table. If your
|
||||
C library uses a table to map lower-case numbers to upper-case numbers,
|
||||
and vice versa, you should define <code>__to_type</code> to be the type of the
|
||||
elements in that table. If you don't mind taking a minor performance
|
||||
penalty, or if your library doesn't implement <code>toupper</code> and
|
||||
<code>tolower</code> in this way, you can pick any pointer-to-integer type,
|
||||
but you must still define the type.
|
||||
|
||||
<p>The enumeration should give definitions for all the values in the above
|
||||
example, using the values from your native <code><ctype.h></code>. They can
|
||||
be given symbolically (as above), or numerically, if you prefer. You do
|
||||
not have to include <code><ctype.h></code> in this header; it will always be
|
||||
included before <code>ctype_base.h</code> is included.
|
||||
|
||||
<p>The next file to write is <code>ctype_noninline.h</code>, which also does
|
||||
not require include guards. This file defines a few member functions
|
||||
that will be included in <code>include/bits/locale_facets.h</code>. The first
|
||||
function that must be written is the <code>ctype<char>::ctype</code>
|
||||
constructor. Here is the IRIX example:
|
||||
|
||||
<pre class="example"> ctype<char>::ctype(const mask* __table = 0, bool __del = false,
|
||||
size_t __refs = 0)
|
||||
: _Ctype_nois<char>(__refs), _M_del(__table != 0 && __del),
|
||||
_M_toupper(NULL),
|
||||
_M_tolower(NULL),
|
||||
_M_ctable(NULL),
|
||||
_M_table(!__table
|
||||
? (const mask*) (__libc_attr._ctype_tbl->_class + 1)
|
||||
: __table)
|
||||
{ }
|
||||
</pre>
|
||||
|
||||
<p>There are two parts of this that you might choose to alter. The first,
|
||||
and most important, is the line involving <code>__libc_attr</code>. That is
|
||||
IRIX system-dependent code that gets the base of the table mapping
|
||||
character codes to attributes. You need to substitute code that obtains
|
||||
the address of this table on your system. If you want to use your
|
||||
operating system's tables to map upper-case letters to lower-case, and
|
||||
vice versa, you should initialize <code>_M_toupper</code> and
|
||||
<code>_M_tolower</code> with those tables, in similar fashion.
|
||||
|
||||
<p>Now, you have to write two functions to convert from upper-case to
|
||||
lower-case, and vice versa. Here are the IRIX versions:
|
||||
|
||||
<pre class="example"> char
|
||||
ctype<char>::do_toupper(char __c) const
|
||||
{ return _toupper(__c); }
|
||||
|
||||
char
|
||||
ctype<char>::do_tolower(char __c) const
|
||||
{ return _tolower(__c); }
|
||||
</pre>
|
||||
|
||||
<p>Your C library provides equivalents to IRIX's <code>_toupper</code> and
|
||||
<code>_tolower</code>. If you initialized <code>_M_toupper</code> and
|
||||
<code>_M_tolower</code> above, then you could use those tables instead.
|
||||
|
||||
<p>Finally, you have to provide two utility functions that convert strings
|
||||
of characters. The versions provided here will always work - but you
|
||||
could use specialized routines for greater performance if you have
|
||||
machinery to do that on your system:
|
||||
|
||||
<pre class="example"> const char*
|
||||
ctype<char>::do_toupper(char* __low, const char* __high) const
|
||||
{
|
||||
while (__low < __high)
|
||||
{
|
||||
*__low = do_toupper(*__low);
|
||||
++__low;
|
||||
}
|
||||
return __high;
|
||||
}
|
||||
|
||||
const char*
|
||||
ctype<char>::do_tolower(char* __low, const char* __high) const
|
||||
{
|
||||
while (__low < __high)
|
||||
{
|
||||
*__low = do_tolower(*__low);
|
||||
++__low;
|
||||
}
|
||||
return __high;
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>You must also provide the <code>ctype_inline.h</code> file, which
|
||||
contains a few more functions. On most systems, you can just copy
|
||||
<code>config/os/generic/ctype_inline.h</code> and use it on your system.
|
||||
|
||||
<p>In detail, the functions provided test characters for particular
|
||||
properties; they are analogous to the functions like <code>isalpha</code> and
|
||||
<code>islower</code> provided by the C library.
|
||||
|
||||
<p>The first function is implemented like this on IRIX:
|
||||
|
||||
<pre class="example"> bool
|
||||
ctype<char>::
|
||||
is(mask __m, char __c) const throw()
|
||||
{ return (_M_table)[(unsigned char)(__c)] & __m; }
|
||||
</pre>
|
||||
|
||||
<p>The <code>_M_table</code> is the table passed in above, in the constructor.
|
||||
This is the table that contains the bitmasks for each character. The
|
||||
implementation here should work on all systems.
|
||||
|
||||
<p>The next function is:
|
||||
|
||||
<pre class="example"> const char*
|
||||
ctype<char>::
|
||||
is(const char* __low, const char* __high, mask* __vec) const throw()
|
||||
{
|
||||
while (__low < __high)
|
||||
*__vec++ = (_M_table)[(unsigned char)(*__low++)];
|
||||
return __high;
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>This function is similar; it copies the masks for all the characters
|
||||
from <code>__low</code> up until <code>__high</code> into the vector given by
|
||||
<code>__vec</code>.
|
||||
|
||||
<p>The last two functions again are entirely generic:
|
||||
|
||||
<pre class="example"> const char*
|
||||
ctype<char>::
|
||||
scan_is(mask __m, const char* __low, const char* __high) const throw()
|
||||
{
|
||||
while (__low < __high && !this->is(__m, *__low))
|
||||
++__low;
|
||||
return __low;
|
||||
}
|
||||
|
||||
const char*
|
||||
ctype<char>::
|
||||
scan_not(mask __m, const char* __low, const char* __high) const throw()
|
||||
{
|
||||
while (__low < __high && this->is(__m, *__low))
|
||||
++__low;
|
||||
return __low;
|
||||
}
|
||||
</pre>
|
||||
|
||||
<div class="node">
|
||||
<p><hr>
|
||||
Node: <a name="Thread%20safety">Thread safety</a>,
|
||||
Next: <a rel="next" accesskey="n" href="#Numeric%20limits">Numeric limits</a>,
|
||||
Previous: <a rel="previous" accesskey="p" href="#Character%20types">Character types</a>,
|
||||
Up: <a rel="up" accesskey="u" href="#Top">Top</a>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<h2 class="chapter">Thread safety</h2>
|
||||
|
||||
<p>The C++ library string functionality requires a couple of atomic
|
||||
operations to provide thread-safety. If you don't take any special
|
||||
action, the library will use stub versions of these functions that are
|
||||
not thread-safe. They will work fine, unless your applications are
|
||||
multi-threaded.
|
||||
|
||||
<p>If you want to provide custom, safe, versions of these functions, there
|
||||
are two distinct approaches. One is to provide a version for your CPU,
|
||||
using assembly language constructs. The other is to use the
|
||||
thread-safety primitives in your operating system. In either case, you
|
||||
make a file called <code>atomicity.h</code>, and the variable
|
||||
<code>ATOMICITYH</code> must point to this file.
|
||||
|
||||
<p>If you are using the assembly-language approach, put this code in
|
||||
<code>config/cpu/<chip>/atomicity.h</code>, where chip is the name of
|
||||
your processor (see <a href="#CPU">CPU</a>). No additional changes are necessary to
|
||||
locate the file in this case; <code>ATOMICITYH</code> will be set by default.
|
||||
|
||||
<p>If you are using the operating system thread-safety primitives approach,
|
||||
you can also put this code in the same CPU directory, in which case no more
|
||||
work is needed to locate the file. For examples of this approach,
|
||||
see the <code>atomicity.h</code> file for IRIX or IA64.
|
||||
|
||||
<p>Alternatively, if the primitives are more closely related to the OS
|
||||
than they are to the CPU, you can put the <code>atomicity.h</code> file in
|
||||
the <a href="#Operating%20system">Operating system</a> directory instead. In this case, you must
|
||||
edit <code>configure.host</code>, and in the switch statement that handles
|
||||
operating systems, override the <code>ATOMICITYH</code> variable to point to
|
||||
the appropriate <code>os_include_dir</code>. For examples of this approach,
|
||||
see the <code>atomicity.h</code> file for AIX.
|
||||
|
||||
<p>With those bits out of the way, you have to actually write
|
||||
<code>atomicity.h</code> itself. This file should be wrapped in an
|
||||
include guard named <code>_GLIBCXX_ATOMICITY_H</code>. It should define one
|
||||
type, and two functions.
|
||||
|
||||
<p>The type is <code>_Atomic_word</code>. Here is the version used on IRIX:
|
||||
|
||||
<pre class="example"> typedef long _Atomic_word;
|
||||
</pre>
|
||||
|
||||
<p>This type must be a signed integral type supporting atomic operations.
|
||||
If you're using the OS approach, use the same type used by your system's
|
||||
primitives. Otherwise, use the type for which your CPU provides atomic
|
||||
primitives.
|
||||
|
||||
<p>Then, you must provide two functions. The bodies of these functions
|
||||
must be equivalent to those provided here, but using atomic operations:
|
||||
|
||||
<pre class="example"> static inline _Atomic_word
|
||||
__attribute__ ((__unused__))
|
||||
__exchange_and_add (_Atomic_word* __mem, int __val)
|
||||
{
|
||||
_Atomic_word __result = *__mem;
|
||||
*__mem += __val;
|
||||
return __result;
|
||||
}
|
||||
|
||||
static inline void
|
||||
__attribute__ ((__unused__))
|
||||
__atomic_add (_Atomic_word* __mem, int __val)
|
||||
{
|
||||
*__mem += __val;
|
||||
}
|
||||
</pre>
|
||||
|
||||
<div class="node">
|
||||
<p><hr>
|
||||
Node: <a name="Numeric%20limits">Numeric limits</a>,
|
||||
Next: <a rel="next" accesskey="n" href="#Libtool">Libtool</a>,
|
||||
Previous: <a rel="previous" accesskey="p" href="#Thread%20safety">Thread safety</a>,
|
||||
Up: <a rel="up" accesskey="u" href="#Top">Top</a>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<h2 class="chapter">Numeric limits</h2>
|
||||
|
||||
<p>The C++ library requires information about the fundamental data types,
|
||||
such as the minimum and maximum representable values of each type.
|
||||
You can define each of these values individually, but it is usually
|
||||
easiest just to indicate how many bits are used in each of the data
|
||||
types and let the library do the rest. For information about the
|
||||
macros to define, see the top of <code>include/bits/std_limits.h</code>.
|
||||
|
||||
<p>If you need to define any macros, you can do so in <code>os_defines.h</code>.
|
||||
However, if all operating systems for your CPU are likely to use the
|
||||
same values, you can provide a CPU-specific file instead so that you
|
||||
do not have to provide the same definitions for each operating system.
|
||||
To take that approach, create a new file called <code>cpu_limits.h</code> in
|
||||
your CPU configuration directory (see <a href="#CPU">CPU</a>).
|
||||
|
||||
<div class="node">
|
||||
<p><hr>
|
||||
Node: <a name="Libtool">Libtool</a>,
|
||||
Next: <a rel="next" accesskey="n" href="#GNU%20Free%20Documentation%20License">GNU Free Documentation License</a>,
|
||||
Previous: <a rel="previous" accesskey="p" href="#Numeric%20limits">Numeric limits</a>,
|
||||
Up: <a rel="up" accesskey="u" href="#Top">Top</a>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<h2 class="chapter">Libtool</h2>
|
||||
|
||||
<p>The C++ library is compiled, archived and linked with libtool.
|
||||
Explaining the full workings of libtool is beyond the scope of this
|
||||
document, but there are a few, particular bits that are necessary for
|
||||
porting.
|
||||
|
||||
<p>Some parts of the libstdc++ library are compiled with the libtool
|
||||
<code>--tags CXX</code> option (the C++ definitions for libtool). Therefore,
|
||||
<code>ltcf-cxx.sh</code> in the top-level directory needs to have the correct
|
||||
logic to compile and archive objects equivalent to the C version of libtool,
|
||||
<code>ltcf-c.sh</code>. Some libtool targets have definitions for C but not
|
||||
for C++, or C++ definitions which have not been kept up to date.
|
||||
|
||||
<p>The C++ run-time library contains initialization code that needs to be
|
||||
run as the library is loaded. Often, that requires linking in special
|
||||
object files when the C++ library is built as a shared library, or
|
||||
taking other system-specific actions.
|
||||
|
||||
<p>The libstdc++ library is linked with the C version of libtool, even
|
||||
though it is a C++ library. Therefore, the C version of libtool needs to
|
||||
ensure that the run-time library initializers are run. The usual way to
|
||||
do this is to build the library using <code>gcc -shared</code>.
|
||||
|
||||
<p>If you need to change how the library is linked, look at
|
||||
<code>ltcf-c.sh</code> in the top-level directory. Find the switch statement
|
||||
that sets <code>archive_cmds</code>. Here, adjust the setting for your
|
||||
operating system.
|
||||
|
||||
<div class="node">
|
||||
<p><hr>
|
||||
Node: <a name="GNU%20Free%20Documentation%20License">GNU Free Documentation License</a>,
|
||||
Previous: <a rel="previous" accesskey="p" href="#Libtool">Libtool</a>,
|
||||
Up: <a rel="up" accesskey="u" href="#Top">Top</a>
|
||||
<br>
|
||||
</div>
|
||||
|
||||
<h2 class="unnumbered">GNU Free Documentation License</h2>
|
||||
|
||||
<div align="center">Version 1.2, November 2002</div>
|
||||
<pre class="display"> Copyright © 2000,2001,2002 Free Software Foundation, Inc.
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
</pre>
|
||||
|
||||
<ol type=1 start=0>
|
||||
<li>PREAMBLE
|
||||
|
||||
<p>The purpose of this License is to make a manual, textbook, or other
|
||||
functional and useful document <dfn>free</dfn> in the sense of freedom: to
|
||||
assure everyone the effective freedom to copy and redistribute it,
|
||||
with or without modifying it, either commercially or noncommercially.
|
||||
Secondarily, this License preserves for the author and publisher a way
|
||||
to get credit for their work, while not being considered responsible
|
||||
for modifications made by others.
|
||||
|
||||
<p>This License is a kind of "copyleft", which means that derivative
|
||||
works of the document must themselves be free in the same sense. It
|
||||
complements the GNU General Public License, which is a copyleft
|
||||
license designed for free software.
|
||||
|
||||
<p>We have designed this License in order to use it for manuals for free
|
||||
software, because free software needs free documentation: a free
|
||||
program should come with manuals providing the same freedoms that the
|
||||
software does. But this License is not limited to software manuals;
|
||||
it can be used for any textual work, regardless of subject matter or
|
||||
whether it is published as a printed book. We recommend this License
|
||||
principally for works whose purpose is instruction or reference.
|
||||
|
||||
</p><li>APPLICABILITY AND DEFINITIONS
|
||||
|
||||
<p>This License applies to any manual or other work, in any medium, that
|
||||
contains a notice placed by the copyright holder saying it can be
|
||||
distributed under the terms of this License. Such a notice grants a
|
||||
world-wide, royalty-free license, unlimited in duration, to use that
|
||||
work under the conditions stated herein. The "Document", below,
|
||||
refers to any such manual or work. Any member of the public is a
|
||||
licensee, and is addressed as "you". You accept the license if you
|
||||
copy, modify or distribute the work in a way requiring permission
|
||||
under copyright law.
|
||||
|
||||
<p>A "Modified Version" of the Document means any work containing the
|
||||
Document or a portion of it, either copied verbatim, or with
|
||||
modifications and/or translated into another language.
|
||||
|
||||
<p>A "Secondary Section" is a named appendix or a front-matter section
|
||||
of the Document that deals exclusively with the relationship of the
|
||||
publishers or authors of the Document to the Document's overall
|
||||
subject (or to related matters) and contains nothing that could fall
|
||||
directly within that overall subject. (Thus, if the Document is in
|
||||
part a textbook of mathematics, a Secondary Section may not explain
|
||||
any mathematics.) The relationship could be a matter of historical
|
||||
connection with the subject or with related matters, or of legal,
|
||||
commercial, philosophical, ethical or political position regarding
|
||||
them.
|
||||
|
||||
<p>The "Invariant Sections" are certain Secondary Sections whose titles
|
||||
are designated, as being those of Invariant Sections, in the notice
|
||||
that says that the Document is released under this License. If a
|
||||
section does not fit the above definition of Secondary then it is not
|
||||
allowed to be designated as Invariant. The Document may contain zero
|
||||
Invariant Sections. If the Document does not identify any Invariant
|
||||
Sections then there are none.
|
||||
|
||||
<p>The "Cover Texts" are certain short passages of text that are listed,
|
||||
as Front-Cover Texts or Back-Cover Texts, in the notice that says that
|
||||
the Document is released under this License. A Front-Cover Text may
|
||||
be at most 5 words, and a Back-Cover Text may be at most 25 words.
|
||||
|
||||
<p>A "Transparent" copy of the Document means a machine-readable copy,
|
||||
represented in a format whose specification is available to the
|
||||
general public, that is suitable for revising the document
|
||||
straightforwardly with generic text editors or (for images composed of
|
||||
pixels) generic paint programs or (for drawings) some widely available
|
||||
drawing editor, and that is suitable for input to text formatters or
|
||||
for automatic translation to a variety of formats suitable for input
|
||||
to text formatters. A copy made in an otherwise Transparent file
|
||||
format whose markup, or absence of markup, has been arranged to thwart
|
||||
or discourage subsequent modification by readers is not Transparent.
|
||||
An image format is not Transparent if used for any substantial amount
|
||||
of text. A copy that is not "Transparent" is called "Opaque".
|
||||
|
||||
<p>Examples of suitable formats for Transparent copies include plain
|
||||
<small>ASCII</small> without markup, Texinfo input format, LaTeX input
|
||||
format, <small>SGML</small> or <small>XML</small> using a publicly available
|
||||
<small>DTD</small>, and standard-conforming simple <small>HTML</small>,
|
||||
PostScript or <small>PDF</small> designed for human modification. Examples
|
||||
of transparent image formats include <small>PNG</small>, <small>XCF</small> and
|
||||
<small>JPG</small>. Opaque formats include proprietary formats that can be
|
||||
read and edited only by proprietary word processors, <small>SGML</small> or
|
||||
<small>XML</small> for which the <small>DTD</small> and/or processing tools are
|
||||
not generally available, and the machine-generated <small>HTML</small>,
|
||||
PostScript or <small>PDF</small> produced by some word processors for
|
||||
output purposes only.
|
||||
|
||||
<p>The "Title Page" means, for a printed book, the title page itself,
|
||||
plus such following pages as are needed to hold, legibly, the material
|
||||
this License requires to appear in the title page. For works in
|
||||
formats which do not have any title page as such, "Title Page" means
|
||||
the text near the most prominent appearance of the work's title,
|
||||
preceding the beginning of the body of the text.
|
||||
|
||||
<p>A section "Entitled XYZ" means a named subunit of the Document whose
|
||||
title either is precisely XYZ or contains XYZ in parentheses following
|
||||
text that translates XYZ in another language. (Here XYZ stands for a
|
||||
specific section name mentioned below, such as "Acknowledgements",
|
||||
"Dedications", "Endorsements", or "History".) To "Preserve the Title"
|
||||
of such a section when you modify the Document means that it remains a
|
||||
section "Entitled XYZ" according to this definition.
|
||||
|
||||
<p>The Document may include Warranty Disclaimers next to the notice which
|
||||
states that this License applies to the Document. These Warranty
|
||||
Disclaimers are considered to be included by reference in this
|
||||
License, but only as regards disclaiming warranties: any other
|
||||
implication that these Warranty Disclaimers may have is void and has
|
||||
no effect on the meaning of this License.
|
||||
|
||||
</p><li>VERBATIM COPYING
|
||||
|
||||
<p>You may copy and distribute the Document in any medium, either
|
||||
commercially or noncommercially, provided that this License, the
|
||||
copyright notices, and the license notice saying this License applies
|
||||
to the Document are reproduced in all copies, and that you add no other
|
||||
conditions whatsoever to those of this License. You may not use
|
||||
technical measures to obstruct or control the reading or further
|
||||
copying of the copies you make or distribute. However, you may accept
|
||||
compensation in exchange for copies. If you distribute a large enough
|
||||
number of copies you must also follow the conditions in section 3.
|
||||
|
||||
<p>You may also lend copies, under the same conditions stated above, and
|
||||
you may publicly display copies.
|
||||
|
||||
</p><li>COPYING IN QUANTITY
|
||||
|
||||
<p>If you publish printed copies (or copies in media that commonly have
|
||||
printed covers) of the Document, numbering more than 100, and the
|
||||
Document's license notice requires Cover Texts, you must enclose the
|
||||
copies in covers that carry, clearly and legibly, all these Cover
|
||||
Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on
|
||||
the back cover. Both covers must also clearly and legibly identify
|
||||
you as the publisher of these copies. The front cover must present
|
||||
the full title with all words of the title equally prominent and
|
||||
visible. You may add other material on the covers in addition.
|
||||
Copying with changes limited to the covers, as long as they preserve
|
||||
the title of the Document and satisfy these conditions, can be treated
|
||||
as verbatim copying in other respects.
|
||||
|
||||
<p>If the required texts for either cover are too voluminous to fit
|
||||
legibly, you should put the first ones listed (as many as fit
|
||||
reasonably) on the actual cover, and continue the rest onto adjacent
|
||||
pages.
|
||||
|
||||
<p>If you publish or distribute Opaque copies of the Document numbering
|
||||
more than 100, you must either include a machine-readable Transparent
|
||||
copy along with each Opaque copy, or state in or with each Opaque copy
|
||||
a computer-network location from which the general network-using
|
||||
public has access to download using public-standard network protocols
|
||||
a complete Transparent copy of the Document, free of added material.
|
||||
If you use the latter option, you must take reasonably prudent steps,
|
||||
when you begin distribution of Opaque copies in quantity, to ensure
|
||||
that this Transparent copy will remain thus accessible at the stated
|
||||
location until at least one year after the last time you distribute an
|
||||
Opaque copy (directly or through your agents or retailers) of that
|
||||
edition to the public.
|
||||
|
||||
<p>It is requested, but not required, that you contact the authors of the
|
||||
Document well before redistributing any large number of copies, to give
|
||||
them a chance to provide you with an updated version of the Document.
|
||||
|
||||
</p><li>MODIFICATIONS
|
||||
|
||||
<p>You may copy and distribute a Modified Version of the Document under
|
||||
the conditions of sections 2 and 3 above, provided that you release
|
||||
the Modified Version under precisely this License, with the Modified
|
||||
Version filling the role of the Document, thus licensing distribution
|
||||
and modification of the Modified Version to whoever possesses a copy
|
||||
of it. In addition, you must do these things in the Modified Version:
|
||||
|
||||
<ol type=A start=1>
|
||||
<li>Use in the Title Page (and on the covers, if any) a title distinct
|
||||
from that of the Document, and from those of previous versions
|
||||
(which should, if there were any, be listed in the History section
|
||||
of the Document). You may use the same title as a previous version
|
||||
if the original publisher of that version gives permission.
|
||||
|
||||
<li>List on the Title Page, as authors, one or more persons or entities
|
||||
responsible for authorship of the modifications in the Modified
|
||||
Version, together with at least five of the principal authors of the
|
||||
Document (all of its principal authors, if it has fewer than five),
|
||||
unless they release you from this requirement.
|
||||
|
||||
<li>State on the Title page the name of the publisher of the
|
||||
Modified Version, as the publisher.
|
||||
|
||||
<li>Preserve all the copyright notices of the Document.
|
||||
|
||||
<li>Add an appropriate copyright notice for your modifications
|
||||
adjacent to the other copyright notices.
|
||||
|
||||
<li>Include, immediately after the copyright notices, a license notice
|
||||
giving the public permission to use the Modified Version under the
|
||||
terms of this License, in the form shown in the Addendum below.
|
||||
|
||||
<li>Preserve in that license notice the full lists of Invariant Sections
|
||||
and required Cover Texts given in the Document's license notice.
|
||||
|
||||
<li>Include an unaltered copy of this License.
|
||||
|
||||
<li>Preserve the section Entitled "History", Preserve its Title, and add
|
||||
to it an item stating at least the title, year, new authors, and
|
||||
publisher of the Modified Version as given on the Title Page. If
|
||||
there is no section Entitled "History" in the Document, create one
|
||||
stating the title, year, authors, and publisher of the Document as
|
||||
given on its Title Page, then add an item describing the Modified
|
||||
Version as stated in the previous sentence.
|
||||
|
||||
<li>Preserve the network location, if any, given in the Document for
|
||||
public access to a Transparent copy of the Document, and likewise
|
||||
the network locations given in the Document for previous versions
|
||||
it was based on. These may be placed in the "History" section.
|
||||
You may omit a network location for a work that was published at
|
||||
least four years before the Document itself, or if the original
|
||||
publisher of the version it refers to gives permission.
|
||||
|
||||
<li>For any section Entitled "Acknowledgements" or "Dedications", Preserve
|
||||
the Title of the section, and preserve in the section all the
|
||||
substance and tone of each of the contributor acknowledgements and/or
|
||||
dedications given therein.
|
||||
|
||||
<li>Preserve all the Invariant Sections of the Document,
|
||||
unaltered in their text and in their titles. Section numbers
|
||||
or the equivalent are not considered part of the section titles.
|
||||
|
||||
<li>Delete any section Entitled "Endorsements". Such a section
|
||||
may not be included in the Modified Version.
|
||||
|
||||
<li>Do not retitle any existing section to be Entitled "Endorsements" or
|
||||
to conflict in title with any Invariant Section.
|
||||
|
||||
<li>Preserve any Warranty Disclaimers.
|
||||
</ol>
|
||||
|
||||
<p>If the Modified Version includes new front-matter sections or
|
||||
appendices that qualify as Secondary Sections and contain no material
|
||||
copied from the Document, you may at your option designate some or all
|
||||
of these sections as invariant. To do this, add their titles to the
|
||||
list of Invariant Sections in the Modified Version's license notice.
|
||||
These titles must be distinct from any other section titles.
|
||||
|
||||
<p>You may add a section Entitled "Endorsements", provided it contains
|
||||
nothing but endorsements of your Modified Version by various
|
||||
parties--for example, statements of peer review or that the text has
|
||||
been approved by an organization as the authoritative definition of a
|
||||
standard.
|
||||
|
||||
<p>You may add a passage of up to five words as a Front-Cover Text, and a
|
||||
passage of up to 25 words as a Back-Cover Text, to the end of the list
|
||||
of Cover Texts in the Modified Version. Only one passage of
|
||||
Front-Cover Text and one of Back-Cover Text may be added by (or
|
||||
through arrangements made by) any one entity. If the Document already
|
||||
includes a cover text for the same cover, previously added by you or
|
||||
by arrangement made by the same entity you are acting on behalf of,
|
||||
you may not add another; but you may replace the old one, on explicit
|
||||
permission from the previous publisher that added the old one.
|
||||
|
||||
<p>The author(s) and publisher(s) of the Document do not by this License
|
||||
give permission to use their names for publicity for or to assert or
|
||||
imply endorsement of any Modified Version.
|
||||
|
||||
</p><li>COMBINING DOCUMENTS
|
||||
|
||||
<p>You may combine the Document with other documents released under this
|
||||
License, under the terms defined in section 4 above for modified
|
||||
versions, provided that you include in the combination all of the
|
||||
Invariant Sections of all of the original documents, unmodified, and
|
||||
list them all as Invariant Sections of your combined work in its
|
||||
license notice, and that you preserve all their Warranty Disclaimers.
|
||||
|
||||
<p>The combined work need only contain one copy of this License, and
|
||||
multiple identical Invariant Sections may be replaced with a single
|
||||
copy. If there are multiple Invariant Sections with the same name but
|
||||
different contents, make the title of each such section unique by
|
||||
adding at the end of it, in parentheses, the name of the original
|
||||
author or publisher of that section if known, or else a unique number.
|
||||
Make the same adjustment to the section titles in the list of
|
||||
Invariant Sections in the license notice of the combined work.
|
||||
|
||||
<p>In the combination, you must combine any sections Entitled "History"
|
||||
in the various original documents, forming one section Entitled
|
||||
"History"; likewise combine any sections Entitled "Acknowledgements",
|
||||
and any sections Entitled "Dedications". You must delete all
|
||||
sections Entitled "Endorsements."
|
||||
|
||||
</p><li>COLLECTIONS OF DOCUMENTS
|
||||
|
||||
<p>You may make a collection consisting of the Document and other documents
|
||||
released under this License, and replace the individual copies of this
|
||||
License in the various documents with a single copy that is included in
|
||||
the collection, provided that you follow the rules of this License for
|
||||
verbatim copying of each of the documents in all other respects.
|
||||
|
||||
<p>You may extract a single document from such a collection, and distribute
|
||||
it individually under this License, provided you insert a copy of this
|
||||
License into the extracted document, and follow this License in all
|
||||
other respects regarding verbatim copying of that document.
|
||||
|
||||
</p><li>AGGREGATION WITH INDEPENDENT WORKS
|
||||
|
||||
<p>A compilation of the Document or its derivatives with other separate
|
||||
and independent documents or works, in or on a volume of a storage or
|
||||
distribution medium, is called an "aggregate" if the copyright
|
||||
resulting from the compilation is not used to limit the legal rights
|
||||
of the compilation's users beyond what the individual works permit.
|
||||
When the Document is included an aggregate, this License does not
|
||||
apply to the other works in the aggregate which are not themselves
|
||||
derivative works of the Document.
|
||||
|
||||
<p>If the Cover Text requirement of section 3 is applicable to these
|
||||
copies of the Document, then if the Document is less than one half of
|
||||
the entire aggregate, the Document's Cover Texts may be placed on
|
||||
covers that bracket the Document within the aggregate, or the
|
||||
electronic equivalent of covers if the Document is in electronic form.
|
||||
Otherwise they must appear on printed covers that bracket the whole
|
||||
aggregate.
|
||||
|
||||
</p><li>TRANSLATION
|
||||
|
||||
<p>Translation is considered a kind of modification, so you may
|
||||
distribute translations of the Document under the terms of section 4.
|
||||
Replacing Invariant Sections with translations requires special
|
||||
permission from their copyright holders, but you may include
|
||||
translations of some or all Invariant Sections in addition to the
|
||||
original versions of these Invariant Sections. You may include a
|
||||
translation of this License, and all the license notices in the
|
||||
Document, and any Warrany Disclaimers, provided that you also include
|
||||
the original English version of this License and the original versions
|
||||
of those notices and disclaimers. In case of a disagreement between
|
||||
the translation and the original version of this License or a notice
|
||||
or disclaimer, the original version will prevail.
|
||||
|
||||
<p>If a section in the Document is Entitled "Acknowledgements",
|
||||
"Dedications", or "History", the requirement (section 4) to Preserve
|
||||
its Title (section 1) will typically require changing the actual
|
||||
title.
|
||||
|
||||
</p><li>TERMINATION
|
||||
|
||||
<p>You may not copy, modify, sublicense, or distribute the Document except
|
||||
as expressly provided for under this License. Any other attempt to
|
||||
copy, modify, sublicense or distribute the Document is void, and will
|
||||
automatically terminate your rights under this License. However,
|
||||
parties who have received copies, or rights, from you under this
|
||||
License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
</p><li>FUTURE REVISIONS OF THIS LICENSE
|
||||
|
||||
<p>The Free Software Foundation may publish new, revised versions
|
||||
of the GNU Free Documentation License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns. See
|
||||
<a href="http://www.gnu.org/copyleft/">http://www.gnu.org/copyleft/</a>.
|
||||
|
||||
<p>Each version of the License is given a distinguishing version number.
|
||||
If the Document specifies that a particular numbered version of this
|
||||
License "or any later version" applies to it, you have the option of
|
||||
following the terms and conditions either of that specified version or
|
||||
of any later version that has been published (not as a draft) by the
|
||||
Free Software Foundation. If the Document does not specify a version
|
||||
number of this License, you may choose any version ever published (not
|
||||
as a draft) by the Free Software Foundation.
|
||||
</ol>
|
||||
|
||||
<h3 class="unnumberedsec">ADDENDUM: How to use this License for your documents</h3>
|
||||
|
||||
<p>To use this License in a document you have written, include a copy of
|
||||
the License in the document and put the following copyright and
|
||||
license notices just after the title page:
|
||||
|
||||
<pre class="smallexample"> Copyright (C) <var>year</var> <var>your name</var>.
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.2
|
||||
or any later version published by the Free Software Foundation;
|
||||
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
|
||||
A copy of the license is included in the section entitled ``GNU
|
||||
Free Documentation License''.
|
||||
</pre>
|
||||
|
||||
<p>If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts,
|
||||
replace the "with...Texts." line with this:
|
||||
|
||||
<pre class="smallexample"> with the Invariant Sections being <var>list their titles</var>, with
|
||||
the Front-Cover Texts being <var>list</var>, and with the Back-Cover Texts
|
||||
being <var>list</var>.
|
||||
</pre>
|
||||
|
||||
<p>If you have Invariant Sections without Cover Texts, or some other
|
||||
combination of the three, merge those two alternatives to suit the
|
||||
situation.
|
||||
|
||||
<p>If your document contains nontrivial examples of program code, we
|
||||
recommend releasing these examples in parallel under your choice of
|
||||
free software license, such as the GNU General Public License,
|
||||
to permit their use in free software.
|
||||
|
||||
|
||||
<div class="contents">
|
||||
<h2>Table of Contents</h2>
|
||||
<ul>
|
||||
<li><a name="toc_Top" href="#Top">Porting libstdc++</a>
|
||||
<li><a name="toc_Operating%20system" href="#Operating%20system">Operating system</a>
|
||||
<li><a name="toc_CPU" href="#CPU">CPU</a>
|
||||
<li><a name="toc_Character%20types" href="#Character%20types">Character types</a>
|
||||
<li><a name="toc_Thread%20safety" href="#Thread%20safety">Thread safety</a>
|
||||
<li><a name="toc_Numeric%20limits" href="#Numeric%20limits">Numeric limits</a>
|
||||
<li><a name="toc_Libtool" href="#Libtool">Libtool</a>
|
||||
<li><a name="toc_GNU%20Free%20Documentation%20License" href="#GNU%20Free%20Documentation%20License">GNU Free Documentation License</a>
|
||||
<ul>
|
||||
<li><a href="#GNU%20Free%20Documentation%20License">ADDENDUM: How to use this License for your documents</a>
|
||||
</li></ul>
|
||||
</li></ul>
|
||||
</div>
|
||||
|
||||
</body></html>
|
||||
|
|
@ -1,570 +0,0 @@
|
|||
\input texinfo
|
||||
|
||||
@c ---------------------------------------------------------------------
|
||||
@c Prologue
|
||||
@c ---------------------------------------------------------------------
|
||||
|
||||
@setfilename porting.info
|
||||
@settitle Porting libstdc++-v3
|
||||
@setchapternewpage odd
|
||||
|
||||
@copying
|
||||
Copyright @copyright{} 2000, 2001, 2002, 2003, 2005
|
||||
Free Software Foundation, Inc.
|
||||
|
||||
Permission is granted to copy, distribute and/or modify this document
|
||||
under the terms of the GNU Free Documentation License, Version 1.2 or
|
||||
any later version published by the Free Software Foundation; with the
|
||||
Invariant Sections being ``GNU General Public License'', the Front-Cover
|
||||
texts being (a) (see below), and with the Back-Cover Texts being (b)
|
||||
(see below). A copy of the license is included in the section entitled
|
||||
``GNU Free Documentation License''.
|
||||
|
||||
(a) The FSF's Front-Cover Text is:
|
||||
|
||||
A GNU Manual
|
||||
|
||||
(b) The FSF's Back-Cover Text is:
|
||||
|
||||
You have freedom to copy and modify this GNU Manual, like GNU
|
||||
software. Copies published by the Free Software Foundation raise
|
||||
funds for GNU development.
|
||||
@end copying
|
||||
|
||||
@ifinfo
|
||||
This file explains how to port libstdc++-v3 (the GNU C++ library) to
|
||||
a new target.
|
||||
|
||||
@insertcopying
|
||||
@end ifinfo
|
||||
|
||||
@c ---------------------------------------------------------------------
|
||||
@c Titlepage
|
||||
@c ---------------------------------------------------------------------
|
||||
|
||||
@titlepage
|
||||
@title Porting libstdc++-v3
|
||||
@author Mark Mitchell
|
||||
@page
|
||||
@vskip 0pt plus 1filll
|
||||
@insertcopying
|
||||
@end titlepage
|
||||
|
||||
@c ---------------------------------------------------------------------
|
||||
@c Top
|
||||
@c ---------------------------------------------------------------------
|
||||
|
||||
@node Top
|
||||
@top Porting libstdc++-v3
|
||||
|
||||
This document explains how to port libstdc++-v3 (the GNU C++ library) to
|
||||
a new target.
|
||||
|
||||
In order to make the GNU C++ library (libstdc++-v3) work with a new
|
||||
target, you must edit some configuration files and provide some new
|
||||
header files. Unless this is done, libstdc++-v3 will use generic
|
||||
settings which may not be correct for your target; even if they are
|
||||
correct, they will likely be inefficient.
|
||||
|
||||
Before you get started, make sure that you have a working C library on
|
||||
your target. The C library need not precisely comply with any
|
||||
particular standard, but should generally conform to the requirements
|
||||
imposed by the ANSI/ISO standard.
|
||||
|
||||
In addition, you should try to verify that the C++ compiler generally
|
||||
works. It is difficult to test the C++ compiler without a working
|
||||
library, but you should at least try some minimal test cases.
|
||||
|
||||
(Note that what we think of as a ``target,'' the library refers to as
|
||||
a ``host.'' The comment at the top of @file{configure.ac} explains why.)
|
||||
|
||||
Here are the primary steps required to port the library:
|
||||
|
||||
@menu
|
||||
* Operating system:: Configuring for your operating system.
|
||||
* CPU:: Configuring for your processor chip.
|
||||
* Character types:: Implementing character classification.
|
||||
* Thread safety:: Implementing atomic operations.
|
||||
* Numeric limits:: Implementing numeric limits.
|
||||
* Libtool:: Using libtool.
|
||||
* GNU Free Documentation License:: How you can copy and share this manual.
|
||||
@end menu
|
||||
|
||||
@c ---------------------------------------------------------------------
|
||||
@c Operating system
|
||||
@c ---------------------------------------------------------------------
|
||||
|
||||
@node Operating system
|
||||
@chapter Operating system
|
||||
|
||||
If you are porting to a new operating system (as opposed to a new chip
|
||||
using an existing operating system), you will need to create a new
|
||||
directory in the @file{config/os} hierarchy. For example, the IRIX
|
||||
configuration files are all in @file{config/os/irix}. There is no set
|
||||
way to organize the OS configuration directory. For example,
|
||||
@file{config/os/solaris/solaris-2.6} and
|
||||
@file{config/os/solaris/solaris-2.7} are used as configuration
|
||||
directories for these two versions of Solaris. On the other hand, both
|
||||
Solaris 2.7 and Solaris 2.8 use the @file{config/os/solaris/solaris-2.7}
|
||||
directory. The important information is that there needs to be a
|
||||
directory under @file{config/os} to store the files for your operating
|
||||
system.
|
||||
|
||||
You might have to change the @file{configure.host} file to ensure that
|
||||
your new directory is activated. Look for the switch statement that sets
|
||||
@code{os_include_dir}, and add a pattern to handle your operating system
|
||||
if the default will not suffice. The switch statement switches on only
|
||||
the OS portion of the standard target triplet; e.g., the @code{solaris2.8}
|
||||
in @code{sparc-sun-solaris2.8}. If the new directory is named after the
|
||||
OS portion of the triplet (the default), then nothing needs to be changed.
|
||||
|
||||
The first file to create in this directory, should be called
|
||||
@file{os_defines.h}. This file contains basic macro definitions
|
||||
that are required to allow the C++ library to work with your C library.
|
||||
|
||||
Several libstdc++-v3 source files unconditionally define the macro
|
||||
@code{_POSIX_SOURCE}. On many systems, defining this macro causes
|
||||
large portions of the C library header files to be eliminated
|
||||
at preprocessing time. Therefore, you may have to @code{#undef} this
|
||||
macro, or define other macros (like @code{_LARGEFILE_SOURCE} or
|
||||
@code{__EXTENSIONS__}). You won't know what macros to define or
|
||||
undefine at this point; you'll have to try compiling the library and
|
||||
seeing what goes wrong. If you see errors about calling functions
|
||||
that have not been declared, look in your C library headers to see if
|
||||
the functions are declared there, and then figure out what macros you
|
||||
need to define. You will need to add them to the
|
||||
@code{CPLUSPLUS_CPP_SPEC} macro in the GCC configuration file for your
|
||||
target. It will not work to simply define these macros in
|
||||
@file{os_defines.h}.
|
||||
|
||||
At this time, there are a few libstdc++-v3-specific macros which may be
|
||||
defined:
|
||||
|
||||
@code{_GLIBCXX_USE_C99_CHECK} may be defined to 1 to check C99
|
||||
function declarations (which are not covered by specialization below)
|
||||
found in system headers against versions found in the library headers
|
||||
derived from the standard.
|
||||
|
||||
@code{_GLIBCXX_USE_C99_DYNAMIC} may be defined to an expression that
|
||||
yields 0 if and only if the system headers are exposing proper support
|
||||
for C99 functions (which are not covered by specialization below). If
|
||||
defined, it must be 0 while bootstrapping the compiler/rebuilding the
|
||||
library.
|
||||
|
||||
@code{_GLIBCXX_USE_C99_LONG_LONG_CHECK} may be defined to 1 to check
|
||||
the set of C99 long long function declarations found in system headers
|
||||
against versions found in the library headers derived from the
|
||||
standard.
|
||||
|
||||
@code{_GLIBCXX_USE_C99_LONG_LONG_DYNAMIC} may be defined to an
|
||||
expression that yields 0 if and only if the system headers are
|
||||
exposing proper support for the set of C99 long long functions. If
|
||||
defined, it must be 0 while bootstrapping the compiler/rebuilding the
|
||||
library.
|
||||
|
||||
@code{_GLIBCXX_USE_C99_FP_MACROS_DYNAMIC} may be defined to an
|
||||
expression that yields 0 if and only if the system headers
|
||||
are exposing proper support for the related set of macros. If defined,
|
||||
it must be 0 while bootstrapping the compiler/rebuilding the library.
|
||||
|
||||
@code{_GLIBCXX_USE_C99_FLOAT_TRANSCENDENTALS_CHECK} may be defined
|
||||
to 1 to check the related set of function declarations found in system
|
||||
headers against versions found in the library headers derived from
|
||||
the standard.
|
||||
|
||||
@code{_GLIBCXX_USE_C99_FLOAT_TRANSCENDENTALS_DYNAMIC} may be defined
|
||||
to an expression that yields 0 if and only if the system headers
|
||||
are exposing proper support for the related set of functions. If defined,
|
||||
it must be 0 while bootstrapping the compiler/rebuilding the library.
|
||||
|
||||
Finally, you should bracket the entire file in an include-guard, like
|
||||
this:
|
||||
|
||||
@example
|
||||
#ifndef _GLIBCXX_OS_DEFINES
|
||||
#define _GLIBCXX_OS_DEFINES
|
||||
...
|
||||
#endif
|
||||
@end example
|
||||
|
||||
We recommend copying an existing @file{os_defines.h} to use as a
|
||||
starting point.
|
||||
|
||||
@c ---------------------------------------------------------------------
|
||||
@c CPU
|
||||
@c ---------------------------------------------------------------------
|
||||
|
||||
@node CPU
|
||||
@chapter CPU
|
||||
|
||||
If you are porting to a new chip (as opposed to a new operating system
|
||||
running on an existing chip), you will need to create a new directory in the
|
||||
@file{config/cpu} hierarchy. Much like the @ref{Operating system} setup,
|
||||
there are no strict rules on how to organize the CPU configuration
|
||||
directory, but careful naming choices will allow the configury to find your
|
||||
setup files without explicit help.
|
||||
|
||||
We recommend that for a target triplet @code{<CPU>-<vendor>-<OS>}, you
|
||||
name your configuration directory @file{config/cpu/<CPU>}. If you do this,
|
||||
the configury will find the directory by itself. Otherwise you will need to
|
||||
edit the @file{configure.host} file and, in the switch statement that sets
|
||||
@code{cpu_include_dir}, add a pattern to handle your chip.
|
||||
|
||||
Note that some chip families share a single configuration directory, for
|
||||
example, @code{alpha}, @code{alphaev5}, and @code{alphaev6} all use the
|
||||
@file{config/cpu/alpha} directory, and there is an entry in the
|
||||
@file{configure.host} switch statement to handle this.
|
||||
|
||||
The @code{cpu_include_dir} sets default locations for the files controlling
|
||||
@ref{Thread safety} and @ref{Numeric limits}, if the defaults are not
|
||||
appropriate for your chip.
|
||||
|
||||
|
||||
@c ---------------------------------------------------------------------
|
||||
@c Character types
|
||||
@c ---------------------------------------------------------------------
|
||||
|
||||
@node Character types
|
||||
@chapter Character types
|
||||
|
||||
The library requires that you provide three header files to implement
|
||||
character classification, analogous to that provided by the C libraries
|
||||
@file{<ctype.h>} header. You can model these on the files provided in
|
||||
@file{config/os/generic}. However, these files will almost
|
||||
certainly need some modification.
|
||||
|
||||
The first file to write is @file{ctype_base.h}. This file provides
|
||||
some very basic information about character classification. The libstdc++-v3
|
||||
library assumes that your C library implements @file{<ctype.h>} by using
|
||||
a table (indexed by character code) containing integers, where each of
|
||||
these integers is a bit-mask indicating whether the character is
|
||||
upper-case, lower-case, alphabetic, etc. The @file{ctype_base.h}
|
||||
file gives the type of the integer, and the values of the various bit
|
||||
masks. You will have to peer at your own @file{<ctype.h>} to figure out
|
||||
how to define the values required by this file.
|
||||
|
||||
The @file{ctype_base.h} header file does not need include guards.
|
||||
It should contain a single @code{struct} definition called
|
||||
@code{ctype_base}. This @code{struct} should contain two type
|
||||
declarations, and one enumeration declaration, like this example, taken
|
||||
from the IRIX configuration:
|
||||
|
||||
@example
|
||||
struct ctype_base
|
||||
@{
|
||||
typedef unsigned int mask;
|
||||
typedef int* __to_type;
|
||||
|
||||
enum
|
||||
@{
|
||||
space = _ISspace,
|
||||
print = _ISprint,
|
||||
cntrl = _IScntrl,
|
||||
upper = _ISupper,
|
||||
lower = _ISlower,
|
||||
alpha = _ISalpha,
|
||||
digit = _ISdigit,
|
||||
punct = _ISpunct,
|
||||
xdigit = _ISxdigit,
|
||||
alnum = _ISalnum,
|
||||
graph = _ISgraph
|
||||
@};
|
||||
@};
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
The @code{mask} type is the type of the elements in the table. If your
|
||||
C library uses a table to map lower-case numbers to upper-case numbers,
|
||||
and vice versa, you should define @code{__to_type} to be the type of the
|
||||
elements in that table. If you don't mind taking a minor performance
|
||||
penalty, or if your library doesn't implement @code{toupper} and
|
||||
@code{tolower} in this way, you can pick any pointer-to-integer type,
|
||||
but you must still define the type.
|
||||
|
||||
The enumeration should give definitions for all the values in the above
|
||||
example, using the values from your native @file{<ctype.h>}. They can
|
||||
be given symbolically (as above), or numerically, if you prefer. You do
|
||||
not have to include @file{<ctype.h>} in this header; it will always be
|
||||
included before @file{ctype_base.h} is included.
|
||||
|
||||
The next file to write is @file{ctype_noninline.h}, which also does
|
||||
not require include guards. This file defines a few member functions
|
||||
that will be included in @file{include/bits/locale_facets.h}. The first
|
||||
function that must be written is the @code{ctype<char>::ctype}
|
||||
constructor. Here is the IRIX example:
|
||||
|
||||
@example
|
||||
ctype<char>::ctype(const mask* __table = 0, bool __del = false,
|
||||
size_t __refs = 0)
|
||||
: _Ctype_nois<char>(__refs), _M_del(__table != 0 && __del),
|
||||
_M_toupper(NULL),
|
||||
_M_tolower(NULL),
|
||||
_M_ctable(NULL),
|
||||
_M_table(!__table
|
||||
? (const mask*) (__libc_attr._ctype_tbl->_class + 1)
|
||||
: __table)
|
||||
@{ @}
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
There are two parts of this that you might choose to alter. The first,
|
||||
and most important, is the line involving @code{__libc_attr}. That is
|
||||
IRIX system-dependent code that gets the base of the table mapping
|
||||
character codes to attributes. You need to substitute code that obtains
|
||||
the address of this table on your system. If you want to use your
|
||||
operating system's tables to map upper-case letters to lower-case, and
|
||||
vice versa, you should initialize @code{_M_toupper} and
|
||||
@code{_M_tolower} with those tables, in similar fashion.
|
||||
|
||||
Now, you have to write two functions to convert from upper-case to
|
||||
lower-case, and vice versa. Here are the IRIX versions:
|
||||
|
||||
@example
|
||||
char
|
||||
ctype<char>::do_toupper(char __c) const
|
||||
@{ return _toupper(__c); @}
|
||||
|
||||
char
|
||||
ctype<char>::do_tolower(char __c) const
|
||||
@{ return _tolower(__c); @}
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
Your C library provides equivalents to IRIX's @code{_toupper} and
|
||||
@code{_tolower}. If you initialized @code{_M_toupper} and
|
||||
@code{_M_tolower} above, then you could use those tables instead.
|
||||
|
||||
Finally, you have to provide two utility functions that convert strings
|
||||
of characters. The versions provided here will always work -- but you
|
||||
could use specialized routines for greater performance if you have
|
||||
machinery to do that on your system:
|
||||
|
||||
@example
|
||||
const char*
|
||||
ctype<char>::do_toupper(char* __low, const char* __high) const
|
||||
@{
|
||||
while (__low < __high)
|
||||
@{
|
||||
*__low = do_toupper(*__low);
|
||||
++__low;
|
||||
@}
|
||||
return __high;
|
||||
@}
|
||||
|
||||
const char*
|
||||
ctype<char>::do_tolower(char* __low, const char* __high) const
|
||||
@{
|
||||
while (__low < __high)
|
||||
@{
|
||||
*__low = do_tolower(*__low);
|
||||
++__low;
|
||||
@}
|
||||
return __high;
|
||||
@}
|
||||
@end example
|
||||
|
||||
You must also provide the @file{ctype_inline.h} file, which
|
||||
contains a few more functions. On most systems, you can just copy
|
||||
@file{config/os/generic/ctype_inline.h} and use it on your system.
|
||||
|
||||
In detail, the functions provided test characters for particular
|
||||
properties; they are analogous to the functions like @code{isalpha} and
|
||||
@code{islower} provided by the C library.
|
||||
|
||||
The first function is implemented like this on IRIX:
|
||||
|
||||
@example
|
||||
bool
|
||||
ctype<char>::
|
||||
is(mask __m, char __c) const throw()
|
||||
@{ return (_M_table)[(unsigned char)(__c)] & __m; @}
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
The @code{_M_table} is the table passed in above, in the constructor.
|
||||
This is the table that contains the bitmasks for each character. The
|
||||
implementation here should work on all systems.
|
||||
|
||||
The next function is:
|
||||
|
||||
@example
|
||||
const char*
|
||||
ctype<char>::
|
||||
is(const char* __low, const char* __high, mask* __vec) const throw()
|
||||
@{
|
||||
while (__low < __high)
|
||||
*__vec++ = (_M_table)[(unsigned char)(*__low++)];
|
||||
return __high;
|
||||
@}
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
This function is similar; it copies the masks for all the characters
|
||||
from @code{__low} up until @code{__high} into the vector given by
|
||||
@code{__vec}.
|
||||
|
||||
The last two functions again are entirely generic:
|
||||
|
||||
@example
|
||||
const char*
|
||||
ctype<char>::
|
||||
scan_is(mask __m, const char* __low, const char* __high) const throw()
|
||||
@{
|
||||
while (__low < __high && !this->is(__m, *__low))
|
||||
++__low;
|
||||
return __low;
|
||||
@}
|
||||
|
||||
const char*
|
||||
ctype<char>::
|
||||
scan_not(mask __m, const char* __low, const char* __high) const throw()
|
||||
@{
|
||||
while (__low < __high && this->is(__m, *__low))
|
||||
++__low;
|
||||
return __low;
|
||||
@}
|
||||
@end example
|
||||
|
||||
@c ---------------------------------------------------------------------
|
||||
@c Thread safety
|
||||
@c ---------------------------------------------------------------------
|
||||
|
||||
@node Thread safety
|
||||
@chapter Thread safety
|
||||
|
||||
The C++ library string functionality requires a couple of atomic
|
||||
operations to provide thread-safety. If you don't take any special
|
||||
action, the library will use stub versions of these functions that are
|
||||
not thread-safe. They will work fine, unless your applications are
|
||||
multi-threaded.
|
||||
|
||||
If you want to provide custom, safe, versions of these functions, there
|
||||
are two distinct approaches. One is to provide a version for your CPU,
|
||||
using assembly language constructs. The other is to use the
|
||||
thread-safety primitives in your operating system. In either case, you
|
||||
make a file called @file{atomicity.h}, and the variable
|
||||
@code{ATOMICITYH} must point to this file.
|
||||
|
||||
If you are using the assembly-language approach, put this code in
|
||||
@file{config/cpu/<chip>/atomicity.h}, where chip is the name of
|
||||
your processor (@pxref{CPU}). No additional changes are necessary to
|
||||
locate the file in this case; @code{ATOMICITYH} will be set by default.
|
||||
|
||||
If you are using the operating system thread-safety primitives approach,
|
||||
you can also put this code in the same CPU directory, in which case no more
|
||||
work is needed to locate the file. For examples of this approach,
|
||||
see the @file{atomicity.h} file for IRIX or IA64.
|
||||
|
||||
Alternatively, if the primitives are more closely related to the OS
|
||||
than they are to the CPU, you can put the @file{atomicity.h} file in
|
||||
the @ref{Operating system} directory instead. In this case, you must
|
||||
edit @file{configure.host}, and in the switch statement that handles
|
||||
operating systems, override the @code{ATOMICITYH} variable to point to
|
||||
the appropriate @code{os_include_dir}. For examples of this approach,
|
||||
see the @file{atomicity.h} file for AIX.
|
||||
|
||||
With those bits out of the way, you have to actually write
|
||||
@file{atomicity.h} itself. This file should be wrapped in an
|
||||
include guard named @code{_GLIBCXX_ATOMICITY_H}. It should define one
|
||||
type, and two functions.
|
||||
|
||||
The type is @code{_Atomic_word}. Here is the version used on IRIX:
|
||||
|
||||
@example
|
||||
typedef long _Atomic_word;
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
This type must be a signed integral type supporting atomic operations.
|
||||
If you're using the OS approach, use the same type used by your system's
|
||||
primitives. Otherwise, use the type for which your CPU provides atomic
|
||||
primitives.
|
||||
|
||||
Then, you must provide two functions. The bodies of these functions
|
||||
must be equivalent to those provided here, but using atomic operations:
|
||||
|
||||
@example
|
||||
static inline _Atomic_word
|
||||
__attribute__ ((__unused__))
|
||||
__exchange_and_add (_Atomic_word* __mem, int __val)
|
||||
@{
|
||||
_Atomic_word __result = *__mem;
|
||||
*__mem += __val;
|
||||
return __result;
|
||||
@}
|
||||
|
||||
static inline void
|
||||
__attribute__ ((__unused__))
|
||||
__atomic_add (_Atomic_word* __mem, int __val)
|
||||
@{
|
||||
*__mem += __val;
|
||||
@}
|
||||
@end example
|
||||
|
||||
@c ---------------------------------------------------------------------
|
||||
@c Numeric limits
|
||||
@c ---------------------------------------------------------------------
|
||||
|
||||
@node Numeric limits
|
||||
@chapter Numeric limits
|
||||
|
||||
The C++ library requires information about the fundamental data types,
|
||||
such as the minimum and maximum representable values of each type.
|
||||
You can define each of these values individually, but it is usually
|
||||
easiest just to indicate how many bits are used in each of the data
|
||||
types and let the library do the rest. For information about the
|
||||
macros to define, see the top of @file{include/bits/std_limits.h}.
|
||||
|
||||
If you need to define any macros, you can do so in @file{os_defines.h}.
|
||||
However, if all operating systems for your CPU are likely to use the
|
||||
same values, you can provide a CPU-specific file instead so that you
|
||||
do not have to provide the same definitions for each operating system.
|
||||
To take that approach, create a new file called @file{cpu_limits.h} in
|
||||
your CPU configuration directory (@pxref{CPU}).
|
||||
|
||||
@c ---------------------------------------------------------------------
|
||||
@c Libtool
|
||||
@c ---------------------------------------------------------------------
|
||||
|
||||
@node Libtool
|
||||
@chapter Libtool
|
||||
|
||||
The C++ library is compiled, archived and linked with libtool.
|
||||
Explaining the full workings of libtool is beyond the scope of this
|
||||
document, but there are a few, particular bits that are necessary for
|
||||
porting.
|
||||
|
||||
Some parts of the libstdc++-v3 library are compiled with the libtool
|
||||
@code{--tags CXX} option (the C++ definitions for libtool). Therefore,
|
||||
@file{ltcf-cxx.sh} in the top-level directory needs to have the correct
|
||||
logic to compile and archive objects equivalent to the C version of libtool,
|
||||
@file{ltcf-c.sh}. Some libtool targets have definitions for C but not
|
||||
for C++, or C++ definitions which have not been kept up to date.
|
||||
|
||||
The C++ run-time library contains initialization code that needs to be
|
||||
run as the library is loaded. Often, that requires linking in special
|
||||
object files when the C++ library is built as a shared library, or
|
||||
taking other system-specific actions.
|
||||
|
||||
The libstdc++-v3 library is linked with the C version of libtool, even
|
||||
though it is a C++ library. Therefore, the C version of libtool needs to
|
||||
ensure that the run-time library initializers are run. The usual way to
|
||||
do this is to build the library using @code{gcc -shared}.
|
||||
|
||||
If you need to change how the library is linked, look at
|
||||
@file{ltcf-c.sh} in the top-level directory. Find the switch statement
|
||||
that sets @code{archive_cmds}. Here, adjust the setting for your
|
||||
operating system.
|
||||
|
||||
@c ---------------------------------------------------------------------
|
||||
@c GFDL
|
||||
@c ---------------------------------------------------------------------
|
||||
|
||||
@include fdl.texi
|
||||
|
||||
@c ---------------------------------------------------------------------
|
||||
@c Epilogue
|
||||
@c ---------------------------------------------------------------------
|
||||
|
||||
@contents
|
||||
@bye
|
File diff suppressed because it is too large
Load diff
|
@ -1,435 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta name="AUTHOR" content="pme@gcc.gnu.org (Phil Edwards)" />
|
||||
<meta name="KEYWORDS" content="HOWTO, libstdc++, GCC, g++, libg++, STL" />
|
||||
<meta name="DESCRIPTION" content="HOWTO for the libstdc++ chapter 18." />
|
||||
<meta name="GENERATOR" content="vi and eight fingers" />
|
||||
<title>libstdc++ HOWTO: Chapter 18: Library Support</title>
|
||||
<link rel="StyleSheet" href="../lib3styles.css" type="text/css" />
|
||||
<link rel="Start" href="../documentation.html" type="text/html"
|
||||
title="GNU C++ Standard Library" />
|
||||
<link rel="Prev" href="../17_intro/howto.html" type="text/html"
|
||||
title="Library Introduction" />
|
||||
<link rel="Next" href="../19_diagnostics/howto.html" type="text/html"
|
||||
title="Diagnostics" />
|
||||
<link rel="Copyright" href="../17_intro/license.html" type="text/html" />
|
||||
<link rel="Help" href="../faq/index.html" type="text/html" title="F.A.Q." />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 class="centered"><a name="top">Chapter 18: Library Support</a></h1>
|
||||
|
||||
<p>Chapter 18 deals with the functions called and objects created
|
||||
automatically during the course of a program's existence.
|
||||
</p>
|
||||
<p>While we can't reproduce the contents of the Standard here (you need to
|
||||
get your own copy from your nation's member body; see our homepage for
|
||||
help), we can mention a couple of changes in what kind of support a C++
|
||||
program gets from the Standard Library.
|
||||
</p>
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
<hr />
|
||||
<h1>Contents</h1>
|
||||
<ul>
|
||||
<li><a href="#1">Types</a></li>
|
||||
<li><a href="#2">Implementation properties</a></li>
|
||||
<li><a href="#3">Start and Termination</a></li>
|
||||
<li><a href="#4">Verbose <code>terminate</code></a></li>
|
||||
<li><a href="#5">Dynamic memory management</a></li>
|
||||
<li><a href="#6">RTTI, the ABI, and demangling</a></li>
|
||||
</ul>
|
||||
|
||||
<hr />
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<h2><a name="1">Types</a></h2>
|
||||
<p>All the types that you're used to in C are here in one form or
|
||||
another. The only change that might affect people is the type of
|
||||
NULL: while it is required to be a macro, the definition of that
|
||||
macro is <em>not</em> allowed to be <code>(void*)0</code>, which is
|
||||
often used in C.
|
||||
</p>
|
||||
<p>In g++, NULL is #define'd to be <code>__null</code>, a magic keyword
|
||||
extension of g++.
|
||||
</p>
|
||||
<p>The biggest problem of #defining NULL to be something like
|
||||
"0L" is that the compiler will view that as a long integer
|
||||
before it views it as a pointer, so overloading won't do what you
|
||||
expect. (This is why g++ has a magic extension, so that NULL is
|
||||
always a pointer.)
|
||||
</p>
|
||||
<p>In his book
|
||||
<a href="http://www.awprofessional.com/titles/0-201-92488-9/"><em>Effective C++</em></a>,
|
||||
Scott Meyers points out that the best way to solve this problem is to
|
||||
not overload on pointer-vs-integer types to begin with. He also
|
||||
offers a way to make your own magic NULL that will match pointers
|
||||
before it matches integers:
|
||||
</p>
|
||||
<pre>
|
||||
const // this is a const object...
|
||||
class {
|
||||
public:
|
||||
template<class T> // convertible to any type
|
||||
operator T*() const // of null non-member
|
||||
{ return 0; } // pointer...
|
||||
|
||||
template<class C, class T> // or any type of null
|
||||
operator T C::*() const // member pointer...
|
||||
{ return 0; }
|
||||
|
||||
private:
|
||||
void operator&() const; // whose address can't be
|
||||
// taken (see Item 27)...
|
||||
|
||||
} NULL; // and whose name is NULL
|
||||
</pre>
|
||||
<p>(Cribbed from the published version of
|
||||
<a href="http://www.awprofessional.com/titles/0-201-31015-5/">the
|
||||
Effective C++ CD</a>, reproduced here with permission.)
|
||||
</p>
|
||||
<p>If you aren't using g++ (why?), but you do have a compiler which
|
||||
supports member function templates, then you can use this definition
|
||||
of NULL (be sure to #undef any existing versions). It only helps if
|
||||
you actually use NULL in function calls, though; if you make a call of
|
||||
<code>foo(0);</code> instead of <code>foo(NULL);</code>, then you're back
|
||||
where you started.
|
||||
</p>
|
||||
<p><strong>Added Note:</strong> When we contacted Dr. Meyers to ask
|
||||
permission to
|
||||
print this stuff, it prompted him to run this code through current
|
||||
compilers to see what the state of the art is with respect to member
|
||||
template functions. He posted
|
||||
<a href="http://groups.google.com/groups?oi=djq&selm=an_644660779">
|
||||
an article to Usenet</a> after discovering that the code above is not
|
||||
valid! Even though it has no data members, it still needs a
|
||||
user-defined constructor (which means that the class needs a type name
|
||||
after all). The ctor can have an empty body; it just needs to be
|
||||
there. (Stupid requirement? We think so too, and this will probably
|
||||
be changed in the language itself.)
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="2">Implementation properties</a></h2>
|
||||
<h3><code><limits></code></h3>
|
||||
<p>This header mainly defines traits classes to give access to various
|
||||
implementation defined-aspects of the fundamental types. The
|
||||
traits classes -- fourteen in total -- are all specializations of the
|
||||
template class <code>numeric_limits</code>, documented
|
||||
<a href="http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/structstd_1_1numeric__limits.html">here</a>
|
||||
and defined as follows:
|
||||
</p>
|
||||
<pre>
|
||||
template<typename T> struct class {
|
||||
static const bool is_specialized;
|
||||
static T max() throw();
|
||||
static T min() throw();
|
||||
|
||||
static const int digits;
|
||||
static const int digits10;
|
||||
static const bool is_signed;
|
||||
static const bool is_integer;
|
||||
static const bool is_exact;
|
||||
static const int radix;
|
||||
static T epsilon() throw();
|
||||
static T round_error() throw();
|
||||
|
||||
static const int min_exponent;
|
||||
static const int min_exponent10;
|
||||
static const int max_exponent;
|
||||
static const int max_exponent10;
|
||||
|
||||
static const bool has_infinity;
|
||||
static const bool has_quiet_NaN;
|
||||
static const bool has_signaling_NaN;
|
||||
static const float_denorm_style has_denorm;
|
||||
static const bool has_denorm_loss;
|
||||
static T infinity() throw();
|
||||
static T quiet_NaN() throw();
|
||||
static T denorm_min() throw();
|
||||
|
||||
static const bool is_iec559;
|
||||
static const bool is_bounded;
|
||||
static const bool is_modulo;
|
||||
|
||||
static const bool traps;
|
||||
static const bool tinyness_before;
|
||||
static const float_round_style round_style;
|
||||
};</pre>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="3">Start and Termination</a></h2>
|
||||
<p>Not many changes here to <code><cstdlib></code> (the old stdlib.h).
|
||||
You should note that the <code>abort()</code> function does not call
|
||||
the destructors of automatic nor static objects, so if you're depending
|
||||
on those to do cleanup, it isn't going to happen. (The functions
|
||||
registered with <code>atexit()</code> don't get called either, so you
|
||||
can forget about that possibility, too.)
|
||||
</p>
|
||||
<p>The good old <code>exit()</code> function can be a bit funky, too, until
|
||||
you look closer. Basically, three points to remember are:
|
||||
</p>
|
||||
<ol>
|
||||
<li>Static objects are destroyed in reverse order of their creation.
|
||||
</li>
|
||||
<li>Functions registered with <code>atexit()</code> are called in
|
||||
reverse order of registration, once per registration call.
|
||||
(This isn't actually new.)
|
||||
</li>
|
||||
<li>The previous two actions are "interleaved," that is,
|
||||
given this pseudocode:
|
||||
<pre>
|
||||
extern "C or C++" void f1 (void);
|
||||
extern "C or C++" void f2 (void);
|
||||
|
||||
static Thing obj1;
|
||||
atexit(f1);
|
||||
static Thing obj2;
|
||||
atexit(f2);
|
||||
</pre>
|
||||
then at a call of <code>exit()</code>, f2 will be called, then
|
||||
obj2 will be destroyed, then f1 will be called, and finally obj1
|
||||
will be destroyed. If f1 or f2 allow an exception to propagate
|
||||
out of them, Bad Things happen.
|
||||
</li>
|
||||
</ol>
|
||||
<p>Note also that <code>atexit()</code> is only required to store 32
|
||||
functions, and the compiler/library might already be using some of
|
||||
those slots. If you think you may run out, we recommend using
|
||||
the xatexit/xexit combination from libiberty, which has no such limit.
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="4">Verbose <code>terminate</code></a></h2>
|
||||
<p>If you are having difficulty with uncaught exceptions and want a
|
||||
little bit of help debugging the causes of the core dumps, you can
|
||||
make use of a GNU extension in GCC 3.1 and later:
|
||||
</p>
|
||||
<pre>
|
||||
#include <exception>
|
||||
|
||||
int main()
|
||||
{
|
||||
std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
|
||||
...
|
||||
|
||||
throw <em>anything</em>;
|
||||
}</pre>
|
||||
<p>The <code> __verbose_terminate_handler </code> function obtains the name
|
||||
of the current exception, attempts to demangle it, and prints it to
|
||||
stderr. If the exception is derived from <code> std::exception </code>
|
||||
then the output from <code>what()</code> will be included.
|
||||
</p>
|
||||
<p>Any replacement termination function is required to kill the program
|
||||
without returning; this one calls abort.
|
||||
</p>
|
||||
<p>For example:
|
||||
</p>
|
||||
<pre>
|
||||
#include <exception>
|
||||
#include <stdexcept>
|
||||
|
||||
struct argument_error : public std::runtime_error
|
||||
{
|
||||
argument_error(const std::string& s): std::runtime_error(s) { }
|
||||
};
|
||||
|
||||
int main(int argc)
|
||||
{
|
||||
std::set_terminate(__gnu_cxx::__verbose_terminate_handler);
|
||||
if (argc > 5)
|
||||
throw argument_error("argc is greater than 5!");
|
||||
else
|
||||
throw argc;
|
||||
}
|
||||
</pre>
|
||||
<p>In GCC 3.1 and later, this gives
|
||||
</p>
|
||||
<pre>
|
||||
% ./a.out
|
||||
terminate called after throwing a `int'
|
||||
Aborted
|
||||
% ./a.out f f f f f f f f f f f
|
||||
terminate called after throwing an instance of `argument_error'
|
||||
what(): argc is greater than 5!
|
||||
Aborted
|
||||
%</pre>
|
||||
<p>The 'Aborted' line comes from the call to abort(), of course.
|
||||
</p>
|
||||
<p><strong>UPDATE:</strong> Starting with GCC 3.4, this is the default
|
||||
termination handler; nothing need be done to use it. To go back to
|
||||
the previous "silent death" method, simply include
|
||||
<code><exception></code> and <code><cstdlib></code>,
|
||||
and call
|
||||
</p>
|
||||
<pre>
|
||||
std::set_terminate(std::abort);</pre>
|
||||
|
||||
<p>
|
||||
This function will attempt to write to stderr. If your application
|
||||
closes stderr or redirects it to an inappropriate location,
|
||||
<code>__verbose_terminate_handler</code> will behave in an
|
||||
unspecified manner.
|
||||
</p>
|
||||
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<hr />
|
||||
<h2><a name="5">Dynamic memory management</a></h2>
|
||||
<p>There are six flavors each of <code>new</code> and
|
||||
<code>delete</code>, so make certain that you're using the right
|
||||
ones! Here are quickie descriptions of <code>new</code>:
|
||||
</p>
|
||||
<ul>
|
||||
<li>single object form, throwing a <code>bad_alloc</code> on errors;
|
||||
this is what most people are used to using</li>
|
||||
<li>single object "nothrow" form, returning NULL on errors</li>
|
||||
<li>array new, throwing <code>bad_alloc</code> on errors</li>
|
||||
<li>array nothrow new, returning NULL on errors</li>
|
||||
<li>placement new, which does nothing (like it's supposed to)</li>
|
||||
<li>placement array new, which also does nothing</li>
|
||||
</ul>
|
||||
<p>They are distinguished by the parameters that you pass to them, like
|
||||
any other overloaded function. The six flavors of <code>delete</code>
|
||||
are distinguished the same way, but none of them are allowed to throw
|
||||
an exception under any circumstances anyhow. (They match up for
|
||||
completeness' sake.)
|
||||
</p>
|
||||
<p>Remember that it is perfectly okay to call <code>delete</code> on a
|
||||
NULL pointer! Nothing happens, by definition. That is not the
|
||||
same thing as deleting a pointer twice.
|
||||
</p>
|
||||
<p>By default, if one of the "throwing <code>new</code>s" can't
|
||||
allocate the memory requested, it tosses an instance of a
|
||||
<code>bad_alloc</code> exception (or, technically, some class derived
|
||||
from it). You can change this by writing your own function (called a
|
||||
new-handler) and then registering it with <code>set_new_handler()</code>:
|
||||
</p>
|
||||
<pre>
|
||||
typedef void (*PFV)(void);
|
||||
|
||||
static char* safety;
|
||||
static PFV old_handler;
|
||||
|
||||
void my_new_handler ()
|
||||
{
|
||||
delete[] safety;
|
||||
popup_window ("Dude, you are running low on heap memory. You
|
||||
should, like, close some windows, or something.
|
||||
The next time you run out, we're gonna burn!");
|
||||
set_new_handler (old_handler);
|
||||
return;
|
||||
}
|
||||
|
||||
int main ()
|
||||
{
|
||||
safety = new char[500000];
|
||||
old_handler = set_new_handler (&my_new_handler);
|
||||
...
|
||||
}
|
||||
</pre>
|
||||
<p><code>bad_alloc</code> is derived from the base <code>exception</code>
|
||||
class defined in Chapter 19.
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="6">RTTI, the ABI, and demangling</a></h2>
|
||||
<p>If you have read the <a href="../documentation.html#4">source
|
||||
documentation</a> for <code> namespace abi </code> then you are aware
|
||||
of the cross-vendor C++ ABI which we use. One of the exposed
|
||||
functions is the one which we use for demangling in programs like
|
||||
<code>c++filt</code>, and you can use it yourself as well.
|
||||
</p>
|
||||
<p>(The function itself might use different demanglers, but that's the
|
||||
whole point of abstract interfaces. If we change the implementation,
|
||||
you won't notice.)
|
||||
</p>
|
||||
<p>Probably the only times you'll be interested in demangling at runtime
|
||||
are when you're seeing <code>typeid</code> strings in RTTI, or when
|
||||
you're handling the runtime-support exception classes. For example:
|
||||
</p>
|
||||
<pre>
|
||||
#include <exception>
|
||||
#include <iostream>
|
||||
#include <cxxabi.h>
|
||||
|
||||
struct empty { };
|
||||
|
||||
template <typename T, int N>
|
||||
struct bar { };
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
int status;
|
||||
char *realname;
|
||||
|
||||
// exception classes not in <stdexcept>, thrown by the implementation
|
||||
// instead of the user
|
||||
std::bad_exception e;
|
||||
realname = abi::__cxa_demangle(e.what(), 0, 0, &status);
|
||||
std::cout << e.what() << "\t=> " << realname << "\t: " << status << '\n';
|
||||
free(realname);
|
||||
|
||||
|
||||
// typeid
|
||||
bar<empty,17> u;
|
||||
const std::type_info &ti = typeid(u);
|
||||
|
||||
realname = abi::__cxa_demangle(ti.name(), 0, 0, &status);
|
||||
std::cout << ti.name() << "\t=> " << realname << "\t: " << status << '\n';
|
||||
free(realname);
|
||||
|
||||
return 0;
|
||||
}</pre>
|
||||
<p>With GCC 3.1 and later, this prints
|
||||
</p>
|
||||
<pre>
|
||||
St13bad_exception => std::bad_exception : 0
|
||||
3barI5emptyLi17EE => bar<empty, 17> : 0 </pre>
|
||||
<p>The demangler interface is described in the source documentation
|
||||
linked to above. It is actually written in C, so you don't need to
|
||||
be writing C++ in order to demangle C++. (That also means we have to
|
||||
use crummy memory management facilities, so don't forget to free()
|
||||
the returned char array.)
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<hr />
|
||||
<p class="fineprint"><em>
|
||||
See <a href="../17_intro/license.html">license.html</a> for copying conditions.
|
||||
Comments and suggestions are welcome, and may be sent to
|
||||
<a href="mailto:libstdc++@gcc.gnu.org">the libstdc++ mailing list</a>.
|
||||
</em></p>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,127 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta name="AUTHOR" content="pme@gcc.gnu.org (Phil Edwards)" />
|
||||
<meta name="KEYWORDS" content="HOWTO, libstdc++, GCC, g++, libg++, STL" />
|
||||
<meta name="DESCRIPTION" content="HOWTO for the libstdc++ chapter 19." />
|
||||
<meta name="GENERATOR" content="vi and eight fingers" />
|
||||
<title>libstdc++ HOWTO: Chapter 19: Diagnostics</title>
|
||||
<link rel="StyleSheet" href="../lib3styles.css" type="text/css" />
|
||||
<link rel="Start" href="../documentation.html" type="text/html"
|
||||
title="GNU C++ Standard Library" />
|
||||
<link rel="Prev" href="../18_support/howto.html" type="text/html"
|
||||
title="Library Support" />
|
||||
<link rel="Next" href="../20_util/howto.html" type="text/html"
|
||||
title="General Utilities" />
|
||||
<link rel="Copyright" href="../17_intro/license.html" type="text/html" />
|
||||
<link rel="Help" href="../faq/index.html" type="text/html" title="F.A.Q." />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 class="centered"><a name="top">Chapter 19: Diagnostics</a></h1>
|
||||
|
||||
<p>Chapter 19 deals with program diagnostics, such as exceptions
|
||||
and assertions. You know, all the things we wish weren't even
|
||||
necessary at all.
|
||||
</p>
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
<hr />
|
||||
<h1>Contents</h1>
|
||||
<ul>
|
||||
<li><a href="#1">Adding data to exceptions</a></li>
|
||||
<li><a href="#3">Concept checkers -- <strong>new and improved!</strong></a></li>
|
||||
</ul>
|
||||
|
||||
<hr />
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<h2><a name="1">Adding data to exceptions</a></h2>
|
||||
<p>The standard exception classes carry with them a single string as
|
||||
data (usually describing what went wrong or where the 'throw' took
|
||||
place). It's good to remember that you can add your own data to
|
||||
these exceptions when extending the hierarchy:
|
||||
</p>
|
||||
<pre>
|
||||
struct My_Exception : public std::runtime_error
|
||||
{
|
||||
public:
|
||||
My_Exception (const string& whatarg)
|
||||
: std::runtime_error(whatarg), e(errno), id(GetDataBaseID()) { }
|
||||
int errno_at_time_of_throw() const { return e; }
|
||||
DBID id_of_thing_that_threw() const { return id; }
|
||||
protected:
|
||||
int e;
|
||||
DBID id; // some user-defined type
|
||||
};
|
||||
</pre>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="3">Concept checkers -- <strong>new and improved!</strong></a></h2>
|
||||
<p>Better taste! Less fat! Literally!</p>
|
||||
<p>In 1999, SGI added <em>concept checkers</em> to their implementation
|
||||
of the STL: code which checked the template parameters of
|
||||
instantiated pieces of the STL, in order to insure that the parameters
|
||||
being used met the requirements of the standard. For example,
|
||||
the Standard requires that types passed as template parameters to
|
||||
<code>vector</code> be "Assignable" (which means what you think
|
||||
it means). The checking was done during compilation, and none of
|
||||
the code was executed at runtime.
|
||||
</p>
|
||||
<p>Unfortunately, the size of the compiler files grew significantly
|
||||
as a result. The checking code itself was cumbersome. And bugs
|
||||
were found in it on more than one occasion.
|
||||
</p>
|
||||
<p>The primary author of the checking code, Jeremy Siek, had already
|
||||
started work on a replacement implementation. The new code has been
|
||||
formally reviewed and accepted into
|
||||
<a href="http://www.boost.org/libs/concept_check/concept_check.htm">the
|
||||
Boost libraries</a>, and we are pleased to incorporate it into the
|
||||
GNU C++ library.
|
||||
</p>
|
||||
<p>The new version imposes a much smaller space overhead on the generated
|
||||
object file. The checks are also cleaner and easier to read and
|
||||
understand.
|
||||
</p>
|
||||
<p>They are off by default for all versions of GCC from 3.0 to 3.4 (the
|
||||
latest release at the time of writing).
|
||||
They can be enabled at configure time with
|
||||
<a href="../configopts.html"><code>--enable-concept-checks</code></a>.
|
||||
You can enable them on a per-translation-unit basis with
|
||||
<code>#define _GLIBCXX_CONCEPT_CHECKS</code> for GCC 3.4 and higher
|
||||
(or with <code>#define _GLIBCPP_CONCEPT_CHECKS</code> for versions
|
||||
3.1, 3.2 and 3.3).
|
||||
</p>
|
||||
|
||||
<p>Please note that the upcoming C++ standard has first-class
|
||||
support for template parameter constraints based on concepts in the core
|
||||
language. This will obviate the need for the library-simulated concept
|
||||
checking described above.
|
||||
</p>
|
||||
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<hr />
|
||||
<p class="fineprint"><em>
|
||||
See <a href="../17_intro/license.html">license.html</a> for copying conditions.
|
||||
Comments and suggestions are welcome, and may be sent to
|
||||
<a href="mailto:libstdc++@gcc.gnu.org">the libstdc++ mailing list</a>.
|
||||
</em></p>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,554 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta name="AUTHOR" content="pme@gcc.gnu.org (Phil Edwards) and bkoz@gcc.gnu.org (Benjamin Kosnik)" />
|
||||
<meta name="KEYWORDS" content="c++, libstdc++, g++, allocator, memory" />
|
||||
<meta name="DESCRIPTION" content="Allocators and allocation" />
|
||||
<meta name="GENERATOR" content="emacs and ten fingers" />
|
||||
<title>Allocators and allocation</title>
|
||||
<link rel="StyleSheet" href="../lib3styles.css" type="text/css" />
|
||||
<link rel="Start" href="../documentation.html" type="text/html"
|
||||
title="GNU C++ Standard Library" />
|
||||
<link rel="Bookmark" href="howto.html" type="text/html"
|
||||
title="General Utilities" />
|
||||
<link rel="Copyright" href="../17_intro/license.html" type="text/html" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 class="centered"><a name="top">Allocators and allocation</a></h1>
|
||||
|
||||
<p class="fineprint"><em>
|
||||
The latest version of this document is always available at
|
||||
<a href="http://gcc.gnu.org/onlinedocs/libstdc++/20_util/allocator.html">
|
||||
http://gcc.gnu.org/onlinedocs/libstdc++/20_util/allocator.html</a>.
|
||||
</em></p>
|
||||
|
||||
<p><em>
|
||||
To the <a href="http://gcc.gnu.org/libstdc++/">libstdc++ homepage</a>.
|
||||
</em></p>
|
||||
|
||||
<!-- ####################################################### -->
|
||||
<hr />
|
||||
<p> The C++ Standard encapsulates memory management characteristics
|
||||
for strings, container classes, and parts of iostreams in a
|
||||
template class called <code>std::allocator</code>. This class, and
|
||||
base classes of it, are the superset of available free store
|
||||
("heap") management classes.
|
||||
</p>
|
||||
|
||||
<h3 class="left">
|
||||
<a name="standard_requirements">Standard requirements</a>
|
||||
</h3>
|
||||
<p>The C++ standard only gives a few directives in this area:
|
||||
</p>
|
||||
<ul>
|
||||
<li>When you add elements to a container, and the container must allocate
|
||||
more memory to hold them, the container makes the request via its
|
||||
<code>Allocator</code> template parameter. This includes adding
|
||||
chars to the string class, which acts as a regular STL container
|
||||
in this respect.
|
||||
</li>
|
||||
<li>The default <code>Allocator</code> of every container-of-T is
|
||||
<code>std::allocator<T></code>.
|
||||
</li>
|
||||
<li>The interface of the <code>allocator<T></code> class is
|
||||
extremely simple. It has about 20 public declarations (nested
|
||||
typedefs, member functions, etc), but the two which concern us most
|
||||
are:
|
||||
<pre>
|
||||
T* allocate (size_type n, const void* hint = 0);
|
||||
void deallocate (T* p, size_type n);</pre>
|
||||
(This is a simplification; the real signatures use nested typedefs.)
|
||||
The <code>"n"</code> arguments in both those functions is a
|
||||
<em>count</em> of the number of T's to allocate space for,
|
||||
<em>not their total size</em>.
|
||||
</li>
|
||||
<li>"The storage is obtained by calling
|
||||
<code>::operator new(size_t)</code>, but it is unspecified when or
|
||||
how often this function is called. The use of <code>hint</code>
|
||||
is unspecified, but intended as an aid to locality if an
|
||||
implementation so desires." [20.4.1.1]/6
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p> Complete details cam be found in the C++ standard, look in
|
||||
[20.4 Memory].
|
||||
</p>
|
||||
|
||||
<h3 class="left">
|
||||
<a name="probs_possibilities">Problems and Possibilities</a>
|
||||
</h3>
|
||||
<p>The easiest way of fulfilling the requirements is to call operator new
|
||||
each time a container needs memory, and to call operator delete each
|
||||
time the container releases memory. This method may be
|
||||
<a href="http://gcc.gnu.org/ml/libstdc++/2001-05/msg00105.html">slower</a>
|
||||
than caching the allocations and re-using previously-allocated
|
||||
memory, but has the advantage of working correctly across a wide
|
||||
variety of hardware and operating systems, including large
|
||||
clusters. The <code>__gnu_cxx::new_allocator</code> implements
|
||||
the simple operator new and operator delete semantics, while <code>__gnu_cxx::malloc_allocator</code> implements much the same thing, only with the C language functions <code>std::malloc</code> and <code>std::free</code>.
|
||||
</p>
|
||||
|
||||
<p> Another approach is to use intelligence within the allocator class
|
||||
to cache allocations. This extra machinery can take a variety of
|
||||
forms: a bitmap index, an index into an exponentially increasing
|
||||
power-of-two-sized buckets, or simpler fixed-size pooling cache. The
|
||||
cache is shared among all the containers in the program: when your
|
||||
program's std::vector<int> gets cut in half and frees a bunch of
|
||||
its storage, that memory can be reused by the private
|
||||
std::list<WonkyWidget> brought in from a KDE library that you
|
||||
linked against. And operators new and delete are not always called to
|
||||
pass the memory on, either, which is a speed bonus. Examples of
|
||||
allocators that use these techniques
|
||||
are <code>__gnu_cxx::bitmap_allocator</code>, <code>__gnu_cxx::pool_allocator</code>,
|
||||
and <code>__gnu_cxx::__mt_alloc</code>.
|
||||
</p>
|
||||
|
||||
<p>Depending on the implementation techniques used, the underlying
|
||||
operating system, and compilation environment, scaling caching
|
||||
allocators can be tricky. In particular, order-of-destruction and
|
||||
order-of-creation for memory pools may be difficult to pin down with
|
||||
certainty, which may create problems when used with plugins or loading
|
||||
and unloading shared objects in memory. As such, using caching
|
||||
allocators on systems that do not
|
||||
support <code>abi::__cxa_atexit</code> is not recommended.
|
||||
</p>
|
||||
|
||||
<p>Versions of libstdc++ prior to 3.4 cache allocations in a memory
|
||||
pool, instead of passing through to call the global allocation
|
||||
operators (ie, <code>__gnu_cxx::pool_allocator</code>). More
|
||||
recent versions default to the
|
||||
simpler <code>__gnu_cxx::new_allocator</code>.
|
||||
</p>
|
||||
|
||||
<h3 class="left">
|
||||
<a name="stdallocator">Implementation details of <code>std::allocator</code></a>
|
||||
</h3>
|
||||
<p> The implementation of <code> std::allocator</code> has continued
|
||||
to evolve through successive releases. Here's a brief history.
|
||||
</p>
|
||||
|
||||
<h5 class="left">
|
||||
<a name="30allocator"> 3.0, 3.1, 3.2, 3.3 </a>
|
||||
</h5>
|
||||
<p> During this period, all allocators were written to the SGI
|
||||
style, and all STL containers expected this interface. This
|
||||
interface had a traits class called <code>_Alloc_traits</code> that
|
||||
attempted to provide more information for compile-time allocation
|
||||
selection and optimization. This traits class had another allocator
|
||||
wrapper, <code>__simple_alloc<T,A></code>, which was a
|
||||
wrapper around another allocator, A, which itself is an allocator
|
||||
for instances of T. But wait, there's more:
|
||||
<code>__allocator<T,A></code> is another adapter. Many of
|
||||
the provided allocator classes were SGI style: such classes can be
|
||||
changed to a conforming interface with this wrapper:
|
||||
<code>__allocator<T, __alloc></code> is thus the same as
|
||||
<code>allocator<T></code>.
|
||||
</p>
|
||||
|
||||
<p> The class <code>std::allocator</code> use the typedef
|
||||
<code>__alloc</code> to select an underlying allocator that
|
||||
satisfied memory allocation requests. The selection of this
|
||||
underlying allocator was not user-configurable.
|
||||
</p>
|
||||
|
||||
<h5 class="left">
|
||||
<a name="34allocator"> 3.4 </a>
|
||||
</h5>
|
||||
<p> For this and later releases, the only allocator interface that
|
||||
is support is the standard C++ interface. As such, all STL
|
||||
containers have been adjusted, and all external allocators have
|
||||
been modified to support this change. Because of this,
|
||||
<code>__simple_alloc, __allocator, __alloc, </code> and <code>
|
||||
_Alloc_traits</code> have all been removed.
|
||||
</p>
|
||||
|
||||
<p> The class <code>std::allocator</code> just has typedef,
|
||||
constructor, and rebind members. It inherits from one of the
|
||||
high-speed extension allocators, covered below. Thus, all
|
||||
allocation and deallocation depends on the base class.
|
||||
</p>
|
||||
|
||||
<p> The base class that <code>std::allocator</code> is derived from
|
||||
is not user-configurable.
|
||||
</p>
|
||||
|
||||
<h5 class="left">
|
||||
<a name="benchmarks"> How the default allocation strategy is selected.</a>
|
||||
</h5>
|
||||
<p> It's difficult to pick an allocation strategy that will provide
|
||||
maximum utility, without excessively penalizing some behavior. In
|
||||
fact, it's difficult just deciding which typical actions to measure
|
||||
for speed.
|
||||
</p>
|
||||
|
||||
<p> Three synthetic benchmarks have been created that provide data
|
||||
that is used to compare different C++ allocators. These tests are:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>Insertion. Over multiple iterations, various STL container
|
||||
objects have elements inserted to some maximum amount. A variety
|
||||
of allocators are tested.
|
||||
Test source for <a
|
||||
href="http://gcc.gnu.org/viewcvs/trunk/libstdc%2B%2B-v3/testsuite/performance/23_containers/insert/sequence.cc?view=markup">sequence</a>
|
||||
and <a
|
||||
href="http://gcc.gnu.org/viewcvs/trunk/libstdc%2B%2B-v3/testsuite/performance/23_containers/insert/associative.cc?view=markup">associative</a>
|
||||
containers.
|
||||
</li>
|
||||
|
||||
<li>Insertion and erasure in a multi-threaded environment.
|
||||
This test shows the ability of the allocator to reclaim memory
|
||||
on a pre-thread basis, as well as measuring thread contention
|
||||
for memory resources.
|
||||
Test source
|
||||
<a href="http://gcc.gnu.org/viewcvs/trunk/libstdc%2B%2B-v3/testsuite/performance/23_containers/insert_erase/associative.cc?view=markup">here</a>.
|
||||
</li>
|
||||
|
||||
<li>A threaded producer/consumer model.
|
||||
Test source for
|
||||
<a href="http://gcc.gnu.org/viewcvs/trunk/libstdc%2B%2B-v3/testsuite/performance/23_containers/producer_consumer/sequence.cc?view=markup">sequence</a>
|
||||
and
|
||||
<a href="http://gcc.gnu.org/viewcvs/trunk/libstdc%2B%2B-v3/testsuite/performance/23_containers/producer_consumer/associative.cc?view=markup">associative</a>
|
||||
containers.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h5 class="left">
|
||||
<a name="forcenew"> Disabling memory caching.</a>
|
||||
</h5>
|
||||
<p> In use, <code>std::allocator</code> may allocate and deallocate
|
||||
using implementation-specified strategies and heuristics. Because of
|
||||
this, every call to an allocator object's <code> allocate</code>
|
||||
member function may not actually call the global operator new. This
|
||||
situation is also duplicated for calls to the <code>
|
||||
deallocate</code> member function.
|
||||
</p>
|
||||
|
||||
<p> This can be confusing.
|
||||
</p>
|
||||
|
||||
<p> In particular, this can make debugging memory errors more
|
||||
difficult, especially when using third party tools like valgrind or
|
||||
debug versions of <code> new</code>.
|
||||
</p>
|
||||
|
||||
<p> There are various ways to solve this problem. One would be to
|
||||
use a custom allocator that just called operators <code> new
|
||||
</code> and <code> delete</code> directly, for every
|
||||
allocation. (See include/ext/new_allocator.h, for instance.)
|
||||
However, that option would involve changing source code to use the a
|
||||
non-default allocator. Another option is to force the default
|
||||
allocator to remove caching and pools, and to directly allocate
|
||||
with every call of <code> allocate</code> and directly deallocate
|
||||
with every call of <code> deallocate</code>, regardless of
|
||||
efficiency. As it turns out, this last option is available,
|
||||
although the exact mechanism has evolved with time.
|
||||
</p>
|
||||
|
||||
<p> For GCC releases from 2.95 through the 3.1 series, defining
|
||||
<code>__USE_MALLOC</code> on the gcc command line would change the
|
||||
default allocation strategy to instead use <code> malloc</code> and
|
||||
<code> free</code>. See
|
||||
<a href="../23_containers/howto.html#3">this note</a>
|
||||
for details as to why this was something needing improvement.
|
||||
</p>
|
||||
|
||||
<p>Starting with GCC 3.2, and continued in the 3.3 series, to
|
||||
globally disable memory caching within the library for the
|
||||
default allocator, merely set GLIBCPP_FORCE_NEW (at this time,
|
||||
with any value) in the system's environment before running the
|
||||
program. If your program crashes with GLIBCPP_FORCE_NEW in the
|
||||
environment, it likely means that you linked against objects
|
||||
built against the older library. Code to support this extension
|
||||
is fully compatible with 3.2 code if GLIBCPP_FORCE_NEW is not in
|
||||
the environment.
|
||||
</p>
|
||||
|
||||
<p> As it turns out, the 3.4 code base continues to use this
|
||||
mechanism, only the environment variable has been changed to
|
||||
GLIBCXX_FORCE_NEW.
|
||||
</p>
|
||||
|
||||
<h3 class="left">
|
||||
<a name="ext_allocators">Other allocators</a>
|
||||
</h3>
|
||||
<p> Several other allocators are provided as part of this
|
||||
implementation. The location of the extension allocators and their
|
||||
names have changed, but in all cases, functionality is
|
||||
equivalent. Starting with gcc-3.4, all extension allocators are
|
||||
standard style. Before this point, SGI style was the norm. Because of
|
||||
this, the number of template arguments also changed. Here's a simple
|
||||
chart to track the changes.
|
||||
</p>
|
||||
|
||||
<table title="extension allocators" border="1">
|
||||
<tr>
|
||||
<th>Allocator (3.4)</th>
|
||||
<th>Header (3.4)</th>
|
||||
<th>Allocator (3.[0-3])</th>
|
||||
<th>Header (3.[0-3])</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>__gnu_cxx::new_allocator<T></td>
|
||||
<td><ext/new_allocator.h></td>
|
||||
<td>std::__new_alloc</td>
|
||||
<td><memory></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>__gnu_cxx::malloc_allocator<T></td>
|
||||
<td><ext/malloc_allocator.h></td>
|
||||
<td>std::__malloc_alloc_template<int></td>
|
||||
<td><memory></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>__gnu_cxx::debug_allocator<T></td>
|
||||
<td><ext/debug_allocator.h></td>
|
||||
<td>std::debug_alloc<T></td>
|
||||
<td><memory></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>__gnu_cxx::__pool_alloc<T></td>
|
||||
<td><ext/pool_allocator.h></td>
|
||||
<td>std::__default_alloc_template<bool,int></td>
|
||||
<td><memory></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>__gnu_cxx::__mt_alloc<T></td>
|
||||
<td><ext/mt_allocator.h></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>__gnu_cxx::bitmap_allocator<T></td>
|
||||
<td><ext/bitmap_allocator.h></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p> Releases after gcc-3.4 have continued to add to the collection
|
||||
of available allocators. All of these new allocators are
|
||||
standard-style. The following table includes details, along with
|
||||
the first released version of GCC that included the extension allocator.
|
||||
</p>
|
||||
|
||||
<table title="more extension allocators" border="1">
|
||||
<tr>
|
||||
<th>Allocator</th>
|
||||
<th>Include</th>
|
||||
<th>Version</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>__gnu_cxx::array_allocator<T></td>
|
||||
<td><ext/array_allocator.h></td>
|
||||
<td>4.0.0</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>__gnu_cxx::throw_allocator<T></td>
|
||||
<td><ext/throw_allocator.h></td>
|
||||
<td>4.2.0</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>More details on each of these extension allocators follows. </p>
|
||||
<ul>
|
||||
<li><code>new_allocator</code>
|
||||
<p>Simply wraps <code>::operator new</code>
|
||||
and <code>::operator delete</code>.
|
||||
</p>
|
||||
</li>
|
||||
<li><code>malloc_allocator</code>
|
||||
<p>Simply wraps
|
||||
<code>malloc</code> and <code>free</code>. There is also a hook
|
||||
for an out-of-memory handler (for new/delete this is taken care of
|
||||
elsewhere).
|
||||
</p>
|
||||
</li>
|
||||
<li><code>array_allocator</code>
|
||||
<p>Allows allocations of known and fixed sizes using existing
|
||||
global or external storage allocated via construction of
|
||||
std::tr1::array objects. By using this allocator, fixed size
|
||||
containers (including std::string) can be used without
|
||||
instances calling <code>::operator new</code> and
|
||||
<code>::operator delete</code>. This capability allows the
|
||||
use of STL abstractions without runtime complications or
|
||||
overhead, even in situations such as program startup. For
|
||||
usage examples, please consult the libstdc++ testsuite.
|
||||
</p>
|
||||
</li>
|
||||
<li><code>debug_allocator</code>
|
||||
<p> A wrapper around an
|
||||
arbitrary allocator A. It passes on slightly increased size
|
||||
requests to A, and uses the extra memory to store size information.
|
||||
When a pointer is passed to <code>deallocate()</code>, the stored
|
||||
size is checked, and assert() is used to guarantee they match.
|
||||
</p>
|
||||
</li>
|
||||
<li><code>throw_allocator</code>
|
||||
<p> Includes memory tracking and marking abilities as well as hooks for
|
||||
throwing exceptinos at configurable intervals (including random,
|
||||
all, none).
|
||||
</p>
|
||||
</li>
|
||||
<li><code>__pool_alloc</code>
|
||||
<p> A high-performance, single pool allocator. The reusable
|
||||
memory is shared among identical instantiations of this type.
|
||||
It calls through <code>::operator new</code> to obtain new memory
|
||||
when its lists run out. If a client container requests a block
|
||||
larger than a certain threshold size, then the pool is bypassed,
|
||||
and the allocate/deallocate request is passed to
|
||||
<code>::operator new</code> directly. </p>
|
||||
|
||||
<p> For versions of <code>__pool_alloc</code> after 3.4.0, there is
|
||||
only one template parameter, as per the standard.
|
||||
</p>
|
||||
|
||||
<p> Older versions of this class take a boolean template parameter,
|
||||
called <code>thr</code>, and an integer template parameter,
|
||||
called <code>inst</code>.
|
||||
</p>
|
||||
|
||||
<p>The <code>inst</code> number is used to track additional memory
|
||||
pools. The point of the number is to allow multiple
|
||||
instantiations of the classes without changing the semantics at
|
||||
all. All three of
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
typedef __pool_alloc<true,0> normal;
|
||||
typedef __pool_alloc<true,1> private;
|
||||
typedef __pool_alloc<true,42> also_private;</pre>
|
||||
<p>behave exactly the same way. However, the memory pool for each type
|
||||
(and remember that different instantiations result in different types)
|
||||
remains separate.
|
||||
</p>
|
||||
<p>The library uses <strong>0</strong> in all its instantiations. If you
|
||||
wish to keep separate free lists for a particular purpose, use a
|
||||
different number.
|
||||
</p>
|
||||
<p>The <code>thr</code> boolean determines whether the pool should
|
||||
be manipulated atomically or not. When thr=true, the allocator
|
||||
is is threadsafe, while thr=false, and is slightly faster but
|
||||
unsafe for multiple threads.
|
||||
</p>
|
||||
|
||||
<p>For thread-enabled configurations, the pool is locked with a
|
||||
single big lock. In some situations, this implementation detail may
|
||||
result in severe performance degredation.
|
||||
</p>
|
||||
|
||||
<p>(Note that the GCC thread abstraction layer allows us to provide safe
|
||||
zero-overhead stubs for the threading routines, if threads were
|
||||
disabled at configuration time.)
|
||||
</p>
|
||||
|
||||
</li>
|
||||
|
||||
<li><code>__mt_alloc</code>
|
||||
<p>A high-performance
|
||||
fixed-size allocator. It has its own documentation, found <a
|
||||
href="../ext/mt_allocator.html">here</a>.
|
||||
</p>
|
||||
</li>
|
||||
|
||||
<li><code>bitmap_allocator</code>
|
||||
<p>A high-performance allocator that uses a bit-map to keep track
|
||||
of the used and unused memory locations. It has its own
|
||||
documentation, found <a
|
||||
href="../ext/ballocator_doc.html">here</a>.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3 class="left">
|
||||
<a name="using_custom_allocators">Using a specific allocator</a>
|
||||
</h3>
|
||||
<p>You can specify different memory management schemes on a
|
||||
per-container basis, by overriding the default
|
||||
<code>Allocator</code> template parameter. For example, an easy
|
||||
(but non-portable) method of specifying that only malloc/free
|
||||
should be used instead of the default node allocator is:
|
||||
</p>
|
||||
<pre>
|
||||
std::list <int, __gnu_cxx::malloc_allocator<int> > malloc_list;</pre>
|
||||
Likewise, a debugging form of whichever allocator is currently in use:
|
||||
<pre>
|
||||
std::deque <int, __gnu_cxx::debug_allocator<std::allocator<int> > > debug_deque;</pre>
|
||||
|
||||
|
||||
<h3 class="left">
|
||||
<a name="custom_allocators">Writing custom allocators</a>
|
||||
</h3>
|
||||
<p> Writing a portable C++ allocator would dictate that the
|
||||
interface would look much like the one specified for <code>
|
||||
std::allocator</code>. Additional member functions, but not
|
||||
subtractions, would be permissible.
|
||||
</p>
|
||||
|
||||
<p> Probably the best place to start would be to copy one of the
|
||||
extension allocators already shipped with libstdc++: say, <code>
|
||||
new_allocator </code>.
|
||||
</p>
|
||||
|
||||
|
||||
<h3 class="left">
|
||||
<a name="biblio">Bibliography / Further Reading</a>
|
||||
</h3>
|
||||
<p>
|
||||
ISO/IEC 14882:1998 Programming languages - C++ [20.4 Memory]
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Austern, Matt, C/C++ Users Journal.
|
||||
<a href="http://www.cuj.com/documents/s=8000/cujcexp1812austern/">The Standard Librarian: What Are Allocators Good
|
||||
For?</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Berger, Emery,
|
||||
<a href="http://www.cs.umass.edu/~emery/hoard/"> The Hoard memory allocator </a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Berger, Emery with Ben Zorn & Kathryn McKinley, OOPSLA 2002
|
||||
<a href="http://www.cs.umass.edu/~emery/pubs/berger-oopsla2002.pdf">Reconsidering Custom Memory Allocation</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Kreft, Klaus and Angelika Langer, C++ Report, June 1998
|
||||
<a href="http://www.langer.camelot.de/Articles/C++Report/Allocators/Allocators.html">Allocator Types</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Stroustrup, Bjarne, 19.4 Allocators, The C++ Programming
|
||||
Language, Special Edition, Addison Wesley, Inc. 2000
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Yen, Felix, <a href="http://home.earthlink.net/~brimar/yalloc/">Yalloc: A Recycling C++ Allocator</a>
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<p>Return <a href="#top">to the top of the page</a> or
|
||||
<a href="http://gcc.gnu.org/libstdc++/">to the libstdc++ homepage</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<hr />
|
||||
<p class="fineprint"><em>
|
||||
See <a href="../17_intro/license.html">license.html</a> for copying conditions.
|
||||
Comments and suggestions are welcome, and may be sent to
|
||||
<a href="mailto:libstdc++@gcc.gnu.org">the libstdc++ mailing list</a>.
|
||||
</em></p>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,234 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta name="AUTHOR" content="pme@gcc.gnu.org (Phil Edwards)" />
|
||||
<meta name="KEYWORDS" content="HOWTO, libstdc++, GCC, g++, libg++, STL" />
|
||||
<meta name="DESCRIPTION" content="HOWTO for the libstdc++ chapter 20." />
|
||||
<meta name="GENERATOR" content="vi and eight fingers" />
|
||||
<title>libstdc++ HOWTO: Chapter 20: General Utilities</title>
|
||||
<link rel="StyleSheet" href="../lib3styles.css" type="text/css" />
|
||||
<link rel="Start" href="../documentation.html" type="text/html"
|
||||
title="GNU C++ Standard Library" />
|
||||
<link rel="Prev" href="../19_diagnostics/howto.html" type="text/html"
|
||||
title="Diagnostics" />
|
||||
<link rel="Next" href="../21_strings/howto.html" type="text/html"
|
||||
title="Strings" />
|
||||
<link rel="Bookmark" href="allocator.html" type="text/html"
|
||||
title="Allocators and allocation" />
|
||||
<link rel="Copyright" href="../17_intro/license.html" type="text/html" />
|
||||
<link rel="Help" href="../faq/index.html" type="text/html" title="F.A.Q." />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 class="centered"><a name="top">Chapter 20: General Utilities</a></h1>
|
||||
|
||||
<p>Chapter 20 deals with utility classes and functions, such as
|
||||
the oft-debated <code>auto_ptr<></code>.
|
||||
</p>
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
<hr />
|
||||
<h1>Contents</h1>
|
||||
<ul>
|
||||
<li><a href="#1"><code>auto_ptr</code> is not omnipotent</a></li>
|
||||
<li><a href="#2"><code>auto_ptr</code> inside container classes</a></li>
|
||||
<li><a href="#3">Functors</a></li>
|
||||
<li><a href="#4">Pairs</a></li>
|
||||
<li><a href="#5">Memory allocators</a></li>
|
||||
</ul>
|
||||
|
||||
<hr />
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<h2><a name="1"><code>auto_ptr</code> is not omnipotent</a></h2>
|
||||
<p>I'm not going to try and explain all of the fun and delicious
|
||||
things that can happen with misuse of the auto_ptr class template
|
||||
(called AP here), nor am I going to try and teach you how to use
|
||||
AP safely in the presence of copying. The AP class is a really
|
||||
nifty idea for a smart pointer, but it is one of the dumbest of
|
||||
all the smart pointers -- and that's fine.
|
||||
</p>
|
||||
<p>AP is not meant to be a supersmart solution to all resource
|
||||
leaks everywhere. Neither is it meant to be an effective form
|
||||
of garbage collection (although it can help, a little bit).
|
||||
And it can <em>not</em> be used for arrays!
|
||||
</p>
|
||||
<p>AP <em>is</em> meant to prevent nasty leaks in the presence of
|
||||
exceptions. That's <em>all</em>. This code is AP-friendly:
|
||||
</p>
|
||||
<pre>
|
||||
// not a recommend naming scheme, but good for web-based FAQs
|
||||
typedef std::auto_ptr<MyClass> APMC;
|
||||
|
||||
extern function_taking_MyClass_pointer (MyClass*);
|
||||
extern some_throwable_function ();
|
||||
|
||||
void func (int data)
|
||||
{
|
||||
APMC ap (new MyClass(data));
|
||||
|
||||
some_throwable_function(); // this will throw an exception
|
||||
|
||||
function_taking_MyClass_pointer (ap.get());
|
||||
}
|
||||
</pre>
|
||||
<p>When an exception gets thrown, the instance of MyClass that's
|
||||
been created on the heap will be <code>delete</code>'d as the stack is
|
||||
unwound past <code>func()</code>.
|
||||
</p>
|
||||
<p>Changing that code as follows is <em>not</em> AP-friendly:
|
||||
</p>
|
||||
<pre>
|
||||
APMC ap (new MyClass[22]);
|
||||
</pre>
|
||||
<p>You will get the same problems as you would without the use
|
||||
of AP:
|
||||
</p>
|
||||
<pre>
|
||||
char* array = new char[10]; // array new...
|
||||
...
|
||||
delete array; // ...but single-object delete
|
||||
</pre>
|
||||
<p>AP cannot tell whether the pointer you've passed at creation points
|
||||
to one or many things. If it points to many things, you are about
|
||||
to die. AP is trivial to write, however, so you could write your
|
||||
own <code>auto_array_ptr</code> for that situation (in fact, this has
|
||||
been done many times; check the mailing lists, Usenet, Boost, etc).
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="2"><code>auto_ptr</code> inside container classes</a></h2>
|
||||
<p>All of the <a href="../23_containers/howto.html">containers</a>
|
||||
described in the standard library require their contained types
|
||||
to have, among other things, a copy constructor like this:
|
||||
</p>
|
||||
<pre>
|
||||
struct My_Type
|
||||
{
|
||||
My_Type (My_Type const&);
|
||||
};
|
||||
</pre>
|
||||
<p>Note the const keyword; the object being copied shouldn't change.
|
||||
The template class <code>auto_ptr</code> (called AP here) does not
|
||||
meet this requirement. Creating a new AP by copying an existing
|
||||
one transfers ownership of the pointed-to object, which means that
|
||||
the AP being copied must change, which in turn means that the
|
||||
copy ctors of AP do not take const objects.
|
||||
</p>
|
||||
<p>The resulting rule is simple: <em>Never ever use a container of
|
||||
auto_ptr objects.</em> The standard says that "undefined"
|
||||
behavior is the result, but it is guaranteed to be messy.
|
||||
</p>
|
||||
<p>To prevent you from doing this to yourself, the
|
||||
<a href="../19_diagnostics/howto.html#3">concept checks</a> built
|
||||
in to this implementation will issue an error if you try to
|
||||
compile code like this:
|
||||
</p>
|
||||
<pre>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
void f()
|
||||
{
|
||||
std::vector< std::auto_ptr<int> > vec_ap_int;
|
||||
}
|
||||
</pre>
|
||||
<p>Should you try this with the checks enabled, you will see an error.
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="3">Functors</a></h2>
|
||||
<p>If you don't know what functors are, you're not alone. Many people
|
||||
get slightly the wrong idea. In the interest of not reinventing
|
||||
the wheel, we will refer you to the introduction to the functor
|
||||
concept written by SGI as part of their STL, in
|
||||
<a href="http://www.sgi.com/tech/stl/functors.html">their
|
||||
http://www.sgi.com/tech/stl/functors.html</a>.
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="4">Pairs</a></h2>
|
||||
<p>The <code>pair<T1,T2></code> is a simple and handy way to
|
||||
carry around a pair of objects. One is of type T1, and another of
|
||||
type T2; they may be the same type, but you don't get anything
|
||||
extra if they are. The two members can be accessed directly, as
|
||||
<code>.first</code> and <code>.second</code>.
|
||||
</p>
|
||||
<p>Construction is simple. The default ctor initializes each member
|
||||
with its respective default ctor. The other simple ctor,
|
||||
</p>
|
||||
<pre>
|
||||
pair (const T1& x, const T2& y);
|
||||
</pre>
|
||||
<p>does what you think it does, <code>first</code> getting <code>x</code>
|
||||
and <code>second</code> getting <code>y</code>.
|
||||
</p>
|
||||
<p>There is a copy constructor, but it requires that your compiler
|
||||
handle member function templates:
|
||||
</p>
|
||||
<pre>
|
||||
template <class U, class V> pair (const pair<U,V>& p);
|
||||
</pre>
|
||||
<p>The compiler will convert as necessary from U to T1 and from
|
||||
V to T2 in order to perform the respective initializations.
|
||||
</p>
|
||||
<p>The comparison operators are done for you. Equality
|
||||
of two <code>pair<T1,T2></code>s is defined as both <code>first</code>
|
||||
members comparing equal and both <code>second</code> members comparing
|
||||
equal; this simply delegates responsibility to the respective
|
||||
<code>operator==</code> functions (for types like MyClass) or builtin
|
||||
comparisons (for types like int, char, etc).
|
||||
</p>
|
||||
<p><a name="pairlt">
|
||||
The less-than operator is a bit odd the first time you see it. It
|
||||
is defined as evaluating to:
|
||||
</a>
|
||||
</p>
|
||||
<pre>
|
||||
x.first < y.first ||
|
||||
( !(y.first < x.first) && x.second < y.second )
|
||||
</pre>
|
||||
<p>The other operators are not defined using the <code>rel_ops</code>
|
||||
functions above, but their semantics are the same.
|
||||
</p>
|
||||
<p>Finally, there is a template function called <code>make_pair</code>
|
||||
that takes two references-to-const objects and returns an
|
||||
instance of a pair instantiated on their respective types:
|
||||
</p>
|
||||
<pre>
|
||||
pair<int,MyClass> p = make_pair(4,myobject);
|
||||
</pre>
|
||||
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<hr />
|
||||
<p class="fineprint"><em>
|
||||
See <a href="../17_intro/license.html">license.html</a> for copying conditions.
|
||||
Comments and suggestions are welcome, and may be sent to
|
||||
<a href="mailto:libstdc++@gcc.gnu.org">the libstdc++ mailing list</a>.
|
||||
</em></p>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,419 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta name="KEYWORDS" content="HOWTO, libstdc++, GCC, g++, STL" />
|
||||
<meta name="DESCRIPTION" content="Notes on the shared_ptr implementation." />
|
||||
<title>Notes on the shared_ptr implementation.</title>
|
||||
<link rel="StyleSheet" href="../lib3styles.css" type="text/css" />
|
||||
<link rel="Start" href="../documentation.html" type="text/html"
|
||||
title="GNU C++ Standard Library" />
|
||||
<link rel="Bookmark" href="howto.html" type="text/html" title="General Utilities" />
|
||||
<link rel="Copyright" href="../17_intro/license.html" type="text/html" />
|
||||
<link rel="Help" href="../faq/index.html" type="text/html" title="F.A.Q." />
|
||||
</head>
|
||||
<body>
|
||||
<h1>
|
||||
Notes on the <code>shared_ptr</code> implementation.
|
||||
</h1>
|
||||
<em>
|
||||
prepared by Jonathan Wakely on November 11, 2007
|
||||
</em>
|
||||
|
||||
<h2>
|
||||
1. Abstract
|
||||
</h2>
|
||||
<p>
|
||||
The shared_ptr class template stores a pointer, usually obtained via new,
|
||||
and implements shared ownership semantics.
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
2. What the standard says
|
||||
</h2>
|
||||
|
||||
<blockquote>
|
||||
20.6.6.2 - Class template shared_ptr [util.smartptr.shared]
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
The standard deliberately doesn't require a reference-counted implementation,
|
||||
allowing other techniques such as a circular-linked-list.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
At the time of writing the C++0x working paper doesn't mention how threads
|
||||
affect shared_ptr, but it is likely to follow the existing practice set by
|
||||
<code>boost::shared_ptr</code>. The shared_ptr in libstdc++ is derived
|
||||
from Boost's, so the same rules apply.
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
3. Problems with shared_ptr: TR1 vs C++0x, thread safety.
|
||||
</h2>
|
||||
|
||||
<p>
|
||||
The interface of <code>tr1::shared_ptr</code> was extended for C++0x with
|
||||
support for rvalue-references and the other features from N2351. As
|
||||
with other libstdc++ headers shared by TR1 and C++0x, boost_shared_ptr.h
|
||||
uses conditional compilation, based on the macros _GLIBCXX_INCLUDE_AS_CXX0X
|
||||
and _GLIBCXX_INCLUDE_AS_TR1, to enable and disable features.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
C++0x-only features are: rvalue-ref/move support, allocator support,
|
||||
aliasing constructor, make_shared & allocate_shared. Additionally, the
|
||||
constructors taking auto_ptr parameters are deprecated in C++0x mode.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The
|
||||
<a href="http://boost.org/libs/smart_ptr/shared_ptr.htm#ThreadSafety">Thread
|
||||
Safety</a> section of the Boost shared_ptr documentation says "shared_ptr
|
||||
objects offer the same level of thread safety as built-in types."
|
||||
The implementation must ensure that concurrent updates to separate shared_ptr
|
||||
instances are correct even when those instances share a reference count e.g.
|
||||
</p>
|
||||
<pre>
|
||||
shared_ptr<A> a(new A);
|
||||
shared_ptr<A> b(a);
|
||||
|
||||
// Thread 1 // Thread 2
|
||||
a.reset(); b.reset();
|
||||
</pre>
|
||||
<p>
|
||||
The dynamically-allocated object must be destroyed by exactly one of the
|
||||
threads. Weak references make things even more interesting.
|
||||
The shared state used to implement shared_ptr must be transparent to the
|
||||
user and invariants must be preserved at all times.
|
||||
The key pieces of shared state are the strong and weak reference counts.
|
||||
Updates to these need to be atomic and visible to all threads to ensure
|
||||
correct cleanup of the managed resource (which is, after all, shared_ptr's
|
||||
job!)
|
||||
On multi-processor systems memory synchronisation may be needed so that
|
||||
reference-count updates and the destruction of the managed resource are
|
||||
race-free.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The function <code>_Sp_counted_base::_M_add_ref_lock()</code>, called when
|
||||
obtaining a shared_ptr from a weak_ptr, has to test if the managed
|
||||
resource still exists and either increment the reference count or throw
|
||||
<code>std::bad_weak_ptr</code>.
|
||||
In a multi-threaded program there is a potential race condition if the last
|
||||
reference is dropped (and the managed resource destroyed) between testing
|
||||
the reference count and incrementing it, which could result in a shared_ptr
|
||||
pointing to invalid memory.
|
||||
</p>
|
||||
<p>
|
||||
The Boost shared_ptr (as used in GCC) features a clever lock-free algorithm
|
||||
to avoid the race condition, but this relies on the processor supporting
|
||||
an atomic <em>Compare-And-Swap</em> instruction. For other platforms there
|
||||
are fall-backs using mutex locks. Boost (as of version 1.35) includes
|
||||
several different implementations and the preprocessor selects one based
|
||||
on the compiler, standard library, platform etc. For the version of
|
||||
shared_ptr in libstdc++ the compiler and library are fixed, which makes
|
||||
things much simpler: we have an atomic CAS or we don't, see Lock Policy
|
||||
below for details.
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
4. Design and Implementation Details
|
||||
</h2>
|
||||
|
||||
<p>
|
||||
The shared_ptr code in libstdc++ was kindly donated to GCC by the Boost
|
||||
project and the original authors of the code. The basic design and
|
||||
algorithms are from Boost, the notes below describe details specific to
|
||||
the GCC implementation. Names have been uglified in this implementation,
|
||||
but the design should be recognisable to anyone familiar with the Boost
|
||||
1.32 shared_ptr.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The basic design is an abstract base class, <code>_Sp_counted_base</code> that
|
||||
does the reference-counting and calls virtual functions when the count
|
||||
drops to zero.
|
||||
Derived classes override those functions to destroy resources in a context
|
||||
where the correct dynamic type is known. This is an application of the
|
||||
technique known as type erasure.
|
||||
</p>
|
||||
|
||||
<h3>
|
||||
C++0x and TR1 Implementations
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
The classes derived from <code>_Sp_counted_base</code> (see Class Hierarchy
|
||||
below) and <code>__shared_count</code> are implemented separately for C++0x
|
||||
and TR1, in <tt>bits/boost_sp_shared_count.h</tt> and
|
||||
<tt>tr1/boost_sp_shared_count.h</tt> respectively. All other classes
|
||||
including <code>_Sp_counted_base</code> are shared by both implementations.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The TR1 implementation is considered relatively stable, so is unlikely to
|
||||
change unless bug fixes require it to. If the code that is common to both
|
||||
C++0x and TR1 modes needs to diverge further then it might be necessary to
|
||||
duplicate additional classes and only make changes to the C++0x versions.
|
||||
</p>
|
||||
|
||||
<h3>
|
||||
Lock Policy
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
Libstdc++ has a single <code>_Sp_counted_base</code> class, which is a
|
||||
template parameterized on the enum <code>__gnu_cxx::_Lock_policy</code>.
|
||||
The entire family of classes is parameterized on the lock policy, right up
|
||||
to <code>__shared_ptr</code>, <code>__weak_ptr</code> and
|
||||
<code>__enable_shared_from_this</code>. The actual
|
||||
<code>std::shared_ptr</code> class inherits from <code>__shared_ptr</code>
|
||||
with the lock policy parameter selected automatically based on the thread
|
||||
model and platform that libstdc++ is configured for, so that the best
|
||||
available template specialization will be used. This design is necessary
|
||||
because it would not be conforming for <code>std::shared_ptr</code> to have
|
||||
an extra template parameter, even if it had a default value.
|
||||
The available policies are:
|
||||
</p>
|
||||
|
||||
<dl>
|
||||
<dt><code>_S_Atomic</code></dt>
|
||||
<dd>
|
||||
Selected when GCC supports a builtin atomic compare-and-swap
|
||||
operation on the target processor (see
|
||||
<a href="http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html">Atomic
|
||||
Builtins</a>.)
|
||||
The reference counts are maintained using a lock-free algorithm and GCC's
|
||||
atomic builtins, which provide the required memory synchronisation.
|
||||
</dd>
|
||||
<dt><code>_S_Mutex</code></dt>
|
||||
<dd>
|
||||
The _Sp_counted_base specialization for this policy contains a mutex,
|
||||
which is locked in add_ref_lock(). This policy is used when GCC's atomic
|
||||
builtins aren't available so explicit memory barriers are needed in places.
|
||||
</dd>
|
||||
<dt><code>_S_Single</code></dt>
|
||||
<dd>
|
||||
This policy uses a non-reentrant add_ref_lock() with no locking. It is
|
||||
used when libstdc++ is built without <em>--enable-threads</em>.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<p>
|
||||
For all three policies, reference count increments and decrements are done
|
||||
via the functions in <tt><ext/atomicity.h></tt>, which detect if the
|
||||
program is multi-threaded.
|
||||
If only one thread of execution exists in the program then less expensive
|
||||
non-atomic operations are used.
|
||||
</p>
|
||||
|
||||
<h3>
|
||||
Class Hierarchy
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
A <code>shared_ptr<T></code> contains a pointer of type <code>T*</code>
|
||||
and an object of type <code>__shared_count</code>. The shared_count contains
|
||||
a pointer of type <code>_Sp_counted_base*</code> which points to the object
|
||||
that maintains the reference-counts and destroys the managed resource.
|
||||
</p>
|
||||
|
||||
<dl>
|
||||
<dt><code>_Sp_counted_base<Lp></code></dt>
|
||||
<dd>
|
||||
The base of the hierarchy is parameterized on the lock policy alone.
|
||||
_Sp_counted_base doesn't depend on the type of pointer being managed,
|
||||
it only maintains the reference counts and calls virtual functions when
|
||||
the counts drop to zero. The managed object is destroyed when the last
|
||||
strong reference is dropped, but the _Sp_counted_base itself must exist
|
||||
until the last weak reference is dropped.
|
||||
</dd>
|
||||
<dt><code>_Sp_counted_base_impl<Ptr, Deleter, Lp></code></dt>
|
||||
<dd>
|
||||
Inherits from _Sp_counted_base and stores a pointer of type <code>Ptr</code>
|
||||
and a deleter of type <code>Deleter</code>. <code>_Sp_deleter</code> is
|
||||
used when the user doesn't supply a custom deleter. Unlike Boost's, this
|
||||
default deleter is not "checked" because GCC already issues a warning if
|
||||
<code>delete</code> is used with an incomplete type.
|
||||
This is the only derived type used by <code>tr1::shared_ptr<Ptr></code>
|
||||
and it is never used by <code>std::shared_ptr</code>, which uses one of
|
||||
the following types, depending on how the shared_ptr is constructed.
|
||||
</dd>
|
||||
<dt><code>_Sp_counted_ptr<Ptr, Lp></code></dt>
|
||||
<dd>
|
||||
Inherits from _Sp_counted_base and stores a pointer of type <code>Ptr</code>,
|
||||
which is passed to <code>delete</code> when the last reference is dropped.
|
||||
This is the simplest form and is used when there is no custom deleter or
|
||||
allocator.
|
||||
</dd>
|
||||
<dt><code>_Sp_counted_deleter<Ptr, Deleter, Alloc></code></dt>
|
||||
<dd>
|
||||
Inherits from _Sp_counted_ptr and adds support for custom deleter and
|
||||
allocator. Empty Base Optimization is used for the allocator. This class
|
||||
is used even when the user only provides a custom deleter, in which case
|
||||
<code>std::allocator</code> is used as the allocator.
|
||||
</dd>
|
||||
<dt><code>_Sp_counted_ptr_inplace<Tp, Alloc, Lp></code></dt>
|
||||
<dd>
|
||||
Used by <code>allocate_shared</code> and <code>make_shared</code>.
|
||||
Contains aligned storage to hold an object of type <code>Tp</code>,
|
||||
which is constructed in-place with placement <code>new</code>.
|
||||
Has a variadic template constructor allowing any number of arguments to
|
||||
be forwarded to <code>Tp</code>'s constructor.
|
||||
Unlike the other _Sp_counted_* classes, this one is parameterized on the
|
||||
type of object, not the type of pointer; this is purely a convenience
|
||||
that simplifies the implementation slightly.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h3>
|
||||
Related functions and classes
|
||||
</h3>
|
||||
|
||||
<dl>
|
||||
<dt><code>dynamic_pointer_cast</code>, <code>static_pointer_cast</code>,
|
||||
<code>const_pointer_cast</code></dt>
|
||||
<dd>
|
||||
As noted in N2351, these functions can be implemented non-intrusively using
|
||||
the alias constructor. However the aliasing constructor is only available
|
||||
in C++0x mode, so in TR1 mode these casts rely on three non-standard
|
||||
constructors in shared_ptr and __shared_ptr.
|
||||
In C++0x mode these constructors and the related tag types are not needed.
|
||||
</dd>
|
||||
<dt><code>enable_shared_from_this</code></dt>
|
||||
<dd>
|
||||
The clever overload to detect a base class of type
|
||||
<code>enable_shared_from_this</code> comes straight from Boost.
|
||||
There is an extra overload for <code>__enable_shared_from_this</code> to
|
||||
work smoothly with <code>__shared_ptr<Tp, Lp></code> using any lock
|
||||
policy.
|
||||
</dd>
|
||||
<dt><code>make_shared</code>, <code>allocate_shared</code></dt>
|
||||
<dd>
|
||||
<code>make_shared</code> simply forwards to <code>allocate_shared</code>
|
||||
with <code>std::allocator</code> as the allocator.
|
||||
Although these functions can be implemented non-intrusively using the
|
||||
alias constructor, if they have access to the implementation then it is
|
||||
possible to save storage and reduce the number of heap allocations. The
|
||||
newly constructed object and the _Sp_counted_* can be allocated in a single
|
||||
block and the standard says implementations are "encouraged, but not required,"
|
||||
to do so. This implementation provides additional non-standard constructors
|
||||
(selected with the type <code>_Sp_make_shared_tag</code>) which create an
|
||||
object of type <code>_Sp_counted_ptr_inplace</code> to hold the new object.
|
||||
The returned <code>shared_ptr<A></code> needs to know the address of the
|
||||
new <code>A</code> object embedded in the <code>_Sp_counted_ptr_inplace</code>,
|
||||
but it has no way to access it.
|
||||
This implementation uses a "covert channel" to return the address of the
|
||||
embedded object when <code>get_deleter<_Sp_make_shared_tag>()</code>
|
||||
is called. Users should not try to use this.
|
||||
As well as the extra constructors, this implementation also needs some
|
||||
members of _Sp_counted_deleter to be protected where they could otherwise
|
||||
be private.
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<h2>
|
||||
5. Examples
|
||||
</h2>
|
||||
|
||||
<p>
|
||||
Examples of use can be found in the testsuite, under
|
||||
<tt>testsuite/tr1/2_general_utilities/shared_ptr</tt>.
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
6. Unresolved Issues
|
||||
</h2>
|
||||
|
||||
<p>
|
||||
The resolution to C++ Standard Library issue <a
|
||||
href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#674">674</a>,
|
||||
"shared_ptr interface changes for consistency with N1856" will need to be
|
||||
implemented after it is accepted into the working paper. Issue <a
|
||||
href="http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#743">743</a>
|
||||
might also require changes.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The _S_single policy uses atomics when used in MT code, because it uses
|
||||
the same dispatcher functions that check __gthread_active_p(). This could be
|
||||
addressed by providing template specialisations for some members of
|
||||
_Sp_counted_base<_S_single>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Unlike Boost, this implementation does not use separate classes for the
|
||||
pointer+deleter and pointer+deleter+allocator cases in C++0x mode, combining
|
||||
both into _Sp_counted_deleter and using std::allocator when the user doesn't
|
||||
specify an allocator.
|
||||
If it was found to be beneficial an additional class could easily be added.
|
||||
With the current implementation, the _Sp_counted_deleter and __shared_count
|
||||
constructors taking a custom deleter but no allocator are technically
|
||||
redundant and could be removed, changing callers to always specify an
|
||||
allocator. If a separate pointer+deleter class was added the __shared_count
|
||||
constructor would be needed, so it has been kept for now.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The hack used to get the address of the managed object from
|
||||
_Sp_counted_ptr_inplace::_M_get_deleter() is accessible to users. This
|
||||
could be prevented if get_deleter<_Sp_make_shared_tag>() always
|
||||
returned NULL, since the hack only needs to work at a lower level, not
|
||||
in the public API. This wouldn't be difficult, but hasn't been done since
|
||||
there is no danger of accidental misuse: users already know they are
|
||||
relying on unsupported features if they refer to implementation details
|
||||
such as _Sp_make_shared_tag.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
tr1::_Sp_deleter could be a private member of tr1::__shared_count but it
|
||||
would alter the ABI.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Exposing the alias constructor in TR1 mode could simplify the *_pointer_cast
|
||||
functions.
|
||||
Constructor could be private in TR1 mode, with the cast functions as friends.
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
7. Acknowledgments
|
||||
</h2>
|
||||
<p>
|
||||
The original authors of the Boost shared_ptr, which is really nice code
|
||||
to work with, Peter Dimov in particular for his help and invaluable advice
|
||||
on thread safety.
|
||||
Phillip Jordan and Paolo Carlini for the lock policy implementation.
|
||||
</p>
|
||||
|
||||
|
||||
<h2>
|
||||
8. Bibliography / Referenced Documents
|
||||
</h2>
|
||||
|
||||
<p>
|
||||
N2351 Improving shared_ptr for C++0x, Revision 2
|
||||
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2351.htm">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2351.htm</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
N2456 C++ Standard Library Active Issues List (Revision R52)
|
||||
<a href="http://open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2456.html">http://open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2456.html</a></p>
|
||||
<p>
|
||||
N2461 Working Draft, Standard for Programming Language C++
|
||||
<a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2461.pdf">http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2461.pdf</a>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Boost C++ Libraries documentation - shared_ptr class template
|
||||
<a href="http://boost.org/libs/smart_ptr/shared_ptr.htm">http://boost.org/libs/smart_ptr/shared_ptr.htm</a>
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,159 +0,0 @@
|
|||
From: herbs@cntc.com (Herb Sutter)
|
||||
Subject: Guru of the Week #29: Solution
|
||||
Date: 22 Jan 1998 00:00:00 GMT
|
||||
Message-ID: <6a8q26$9qa@netlab.cs.rpi.edu>
|
||||
Newsgroups: comp.lang.c++.moderated
|
||||
|
||||
|
||||
.--------------------------------------------------------------------.
|
||||
| Guru of the Week problems and solutions are posted regularly on |
|
||||
| news:comp.lang.c++.moderated. For past problems and solutions |
|
||||
| see the GotW archive at http://www.cntc.com. |
|
||||
| Is there a topic you'd like to see covered? mailto:herbs@cntc.com |
|
||||
`--------------------------------------------------------------------'
|
||||
_______________________________________________________
|
||||
|
||||
GotW #29: Strings
|
||||
|
||||
Difficulty: 7 / 10
|
||||
_______________________________________________________
|
||||
|
||||
|
||||
>Write a ci_string class which is identical to the
|
||||
>standard 'string' class, but is case-insensitive in the
|
||||
>same way as the C function stricmp():
|
||||
|
||||
The "how can I make a case-insensitive string?"
|
||||
question is so common that it probably deserves its own
|
||||
FAQ -- hence this issue of GotW.
|
||||
|
||||
Note 1: The stricmp() case-insensitive string
|
||||
comparison function is not part of the C standard, but
|
||||
it is a common extension on many C compilers.
|
||||
|
||||
Note 2: What "case insensitive" actually means depends
|
||||
entirely on your application and language. For
|
||||
example, many languages do not have "cases" at all, and
|
||||
for languages that do you have to decide whether you
|
||||
want accented characters to compare equal to unaccented
|
||||
characters, and so on. This GotW provides guidance on
|
||||
how to implement case-insensitivity for standard
|
||||
strings in whatever sense applies to your particular
|
||||
situation.
|
||||
|
||||
|
||||
Here's what we want to achieve:
|
||||
|
||||
> ci_string s( "AbCdE" );
|
||||
>
|
||||
> // case insensitive
|
||||
> assert( s == "abcde" );
|
||||
> assert( s == "ABCDE" );
|
||||
>
|
||||
> // still case-preserving, of course
|
||||
> assert( strcmp( s.c_str(), "AbCdE" ) == 0 );
|
||||
> assert( strcmp( s.c_str(), "abcde" ) != 0 );
|
||||
|
||||
The key here is to understand what a "string" actually
|
||||
is in standard C++. If you look in your trusty string
|
||||
header, you'll see something like this:
|
||||
|
||||
typedef basic_string<char> string;
|
||||
|
||||
So string isn't really a class... it's a typedef of a
|
||||
template. In turn, the basic_string<> template is
|
||||
declared as follows, in all its glory:
|
||||
|
||||
template<class charT,
|
||||
class traits = char_traits<charT>,
|
||||
class Allocator = allocator<charT> >
|
||||
class basic_string;
|
||||
|
||||
So "string" really means "basic_string<char,
|
||||
char_traits<char>, allocator<char> >". We don't need
|
||||
to worry about the allocator part, but the key here is
|
||||
the char_traits part because char_traits defines how
|
||||
characters interact and compare(!).
|
||||
|
||||
basic_string supplies useful comparison functions that
|
||||
let you compare whether a string is equal to another,
|
||||
less than another, and so on. These string comparisons
|
||||
functions are built on top of character comparison
|
||||
functions supplied in the char_traits template. In
|
||||
particular, the char_traits template supplies character
|
||||
comparison functions named eq(), ne(), and lt() for
|
||||
equality, inequality, and less-than comparisons, and
|
||||
compare() and find() functions to compare and search
|
||||
sequences of characters.
|
||||
|
||||
If we want these to behave differently, all we have to
|
||||
do is provide a different char_traits template! Here's
|
||||
the easiest way:
|
||||
|
||||
struct ci_char_traits : public char_traits<char>
|
||||
// just inherit all the other functions
|
||||
// that we don't need to override
|
||||
{
|
||||
static bool eq( char c1, char c2 ) {
|
||||
return tolower(c1) == tolower(c2);
|
||||
}
|
||||
|
||||
static bool ne( char c1, char c2 ) {
|
||||
return tolower(c1) != tolower(c2);
|
||||
}
|
||||
|
||||
static bool lt( char c1, char c2 ) {
|
||||
return tolower(c1) < tolower(c2);
|
||||
}
|
||||
|
||||
static int compare( const char* s1,
|
||||
const char* s2,
|
||||
size_t n ) {
|
||||
return strnicmp( s1, s2, n );
|
||||
// if available on your compiler,
|
||||
// otherwise you can roll your own
|
||||
}
|
||||
|
||||
static const char*
|
||||
find( const char* s, int n, char a ) {
|
||||
while( n-- > 0 && tolower(*s) != tolower(a) ) {
|
||||
++s;
|
||||
}
|
||||
return n >= 0 ? s : 0;
|
||||
}
|
||||
};
|
||||
|
||||
[N.B. A bug in the original code has been fixed for the
|
||||
GCC documentation, the corrected code was taken from
|
||||
Herb Sutter's book, Exceptional C++]
|
||||
|
||||
And finally, the key that brings it all together:
|
||||
|
||||
typedef basic_string<char, ci_char_traits> ci_string;
|
||||
|
||||
All we've done is created a typedef named "ci_string"
|
||||
which operates exactly like the standard "string",
|
||||
except that it uses ci_char_traits instead of
|
||||
char_traits<char> to get its character comparison
|
||||
rules. Since we've handily made the ci_char_traits
|
||||
rules case-insensitive, we've made ci_string itself
|
||||
case-insensitive without any further surgery -- that
|
||||
is, we have a case-insensitive string without having
|
||||
touched basic_string at all!
|
||||
|
||||
This GotW should give you a flavour for how the
|
||||
basic_string template works and how flexible it is in
|
||||
practice. If you want different comparisons than the
|
||||
ones stricmp() and tolower() give you, just replace the
|
||||
five functions shown above with your own code that
|
||||
performs character comparisons the way that's
|
||||
appropriate in your particular application.
|
||||
|
||||
|
||||
|
||||
Exercise for the reader:
|
||||
|
||||
Is it safe to inherit ci_char_traits from
|
||||
char_traits<char> this way? Why or why not?
|
||||
|
||||
|
|
@ -1,472 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta name="AUTHOR" content="pme@gcc.gnu.org (Phil Edwards)" />
|
||||
<meta name="KEYWORDS" content="HOWTO, libstdc++, GCC, g++, libg++, STL" />
|
||||
<meta name="DESCRIPTION" content="HOWTO for the libstdc++ chapter 21." />
|
||||
<meta name="GENERATOR" content="vi and eight fingers" />
|
||||
<title>libstdc++ HOWTO: Chapter 21: Strings</title>
|
||||
<link rel="StyleSheet" href="../lib3styles.css" type="text/css" />
|
||||
<link rel="Start" href="../documentation.html" type="text/html"
|
||||
title="GNU C++ Standard Library" />
|
||||
<link rel="Prev" href="../20_util/howto.html" type="text/html"
|
||||
title="General Utilities" />
|
||||
<link rel="Next" href="../22_locale/howto.html" type="text/html"
|
||||
title="Localization" />
|
||||
<link rel="Copyright" href="../17_intro/license.html" type="text/html" />
|
||||
<link rel="Help" href="../faq/index.html" type="text/html" title="F.A.Q." />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 class="centered"><a name="top">Chapter 21: Strings</a></h1>
|
||||
|
||||
<p>Chapter 21 deals with the C++ strings library (a welcome relief).
|
||||
</p>
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
<hr />
|
||||
<h1>Contents</h1>
|
||||
<ul>
|
||||
<li><a href="#1">MFC's CString</a></li>
|
||||
<li><a href="#2">A case-insensitive string class</a></li>
|
||||
<li><a href="#3">Breaking a C++ string into tokens</a></li>
|
||||
<li><a href="#4">Simple transformations</a></li>
|
||||
<li><a href="#5">Making strings of arbitrary character types</a></li>
|
||||
<li><a href="#6">Shrink-to-fit strings</a></li>
|
||||
</ul>
|
||||
|
||||
<hr />
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<h2><a name="1">MFC's CString</a></h2>
|
||||
<p>A common lament seen in various newsgroups deals with the Standard
|
||||
string class as opposed to the Microsoft Foundation Class called
|
||||
CString. Often programmers realize that a standard portable
|
||||
answer is better than a proprietary nonportable one, but in porting
|
||||
their application from a Win32 platform, they discover that they
|
||||
are relying on special functions offered by the CString class.
|
||||
</p>
|
||||
<p>Things are not as bad as they seem. In
|
||||
<a href="http://gcc.gnu.org/ml/gcc/1999-04n/msg00236.html">this
|
||||
message</a>, Joe Buck points out a few very important things:
|
||||
</p>
|
||||
<ul>
|
||||
<li>The Standard <code>string</code> supports all the operations
|
||||
that CString does, with three exceptions.
|
||||
</li>
|
||||
<li>Two of those exceptions (whitespace trimming and case
|
||||
conversion) are trivial to implement. In fact, we do so
|
||||
on this page.
|
||||
</li>
|
||||
<li>The third is <code>CString::Format</code>, which allows formatting
|
||||
in the style of <code>sprintf</code>. This deserves some mention:
|
||||
</li>
|
||||
</ul>
|
||||
<p><a name="1.1internal"> <!-- Coming from Chapter 27 -->
|
||||
The old libg++ library had a function called form(), which did much
|
||||
the same thing. But for a Standard solution, you should use the
|
||||
stringstream classes. These are the bridge between the iostream
|
||||
hierarchy and the string class, and they operate with regular
|
||||
streams seamlessly because they inherit from the iostream
|
||||
hierarchy. An quick example:
|
||||
</a>
|
||||
</p>
|
||||
<pre>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
string f (string& incoming) // incoming is "foo N"
|
||||
{
|
||||
istringstream incoming_stream(incoming);
|
||||
string the_word;
|
||||
int the_number;
|
||||
|
||||
incoming_stream >> the_word // extract "foo"
|
||||
>> the_number; // extract N
|
||||
|
||||
ostringstream output_stream;
|
||||
output_stream << "The word was " << the_word
|
||||
<< " and 3*N was " << (3*the_number);
|
||||
|
||||
return output_stream.str();
|
||||
} </pre>
|
||||
<p>A serious problem with CString is a design bug in its memory
|
||||
allocation. Specifically, quoting from that same message:
|
||||
</p>
|
||||
<pre>
|
||||
CString suffers from a common programming error that results in
|
||||
poor performance. Consider the following code:
|
||||
|
||||
CString n_copies_of (const CString& foo, unsigned n)
|
||||
{
|
||||
CString tmp;
|
||||
for (unsigned i = 0; i < n; i++)
|
||||
tmp += foo;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
This function is O(n^2), not O(n). The reason is that each +=
|
||||
causes a reallocation and copy of the existing string. Microsoft
|
||||
applications are full of this kind of thing (quadratic performance
|
||||
on tasks that can be done in linear time) -- on the other hand,
|
||||
we should be thankful, as it's created such a big market for high-end
|
||||
ix86 hardware. :-)
|
||||
|
||||
If you replace CString with string in the above function, the
|
||||
performance is O(n).
|
||||
</pre>
|
||||
<p>Joe Buck also pointed out some other things to keep in mind when
|
||||
comparing CString and the Standard string class:
|
||||
</p>
|
||||
<ul>
|
||||
<li>CString permits access to its internal representation; coders
|
||||
who exploited that may have problems moving to <code>string</code>.
|
||||
</li>
|
||||
<li>Microsoft ships the source to CString (in the files
|
||||
MFC\SRC\Str{core,ex}.cpp), so you could fix the allocation
|
||||
bug and rebuild your MFC libraries.
|
||||
<em><strong>Note:</strong> It looks like the CString shipped
|
||||
with VC++6.0 has fixed this, although it may in fact have been
|
||||
one of the VC++ SPs that did it.</em>
|
||||
</li>
|
||||
<li><code>string</code> operations like this have O(n) complexity
|
||||
<em>if the implementors do it correctly</em>. The libstdc++
|
||||
implementors did it correctly. Other vendors might not.
|
||||
</li>
|
||||
<li>While parts of the SGI STL are used in libstdc++, their
|
||||
string class is not. The SGI <code>string</code> is essentially
|
||||
<code>vector<char></code> and does not do any reference
|
||||
counting like libstdc++'s does. (It is O(n), though.)
|
||||
So if you're thinking about SGI's string or rope classes,
|
||||
you're now looking at four possibilities: CString, the
|
||||
libstdc++ string, the SGI string, and the SGI rope, and this
|
||||
is all before any allocator or traits customizations! (More
|
||||
choices than you can shake a stick at -- want fries with that?)
|
||||
</li>
|
||||
</ul>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="2">A case-insensitive string class</a></h2>
|
||||
<p>The well-known-and-if-it-isn't-well-known-it-ought-to-be
|
||||
<a href="http://www.gotw.ca/gotw/">Guru of the Week</a>
|
||||
discussions held on Usenet covered this topic in January of 1998.
|
||||
Briefly, the challenge was, "write a 'ci_string' class which
|
||||
is identical to the standard 'string' class, but is
|
||||
case-insensitive in the same way as the (common but nonstandard)
|
||||
C function stricmp():"
|
||||
</p>
|
||||
<pre>
|
||||
ci_string s( "AbCdE" );
|
||||
|
||||
// case insensitive
|
||||
assert( s == "abcde" );
|
||||
assert( s == "ABCDE" );
|
||||
|
||||
// still case-preserving, of course
|
||||
assert( strcmp( s.c_str(), "AbCdE" ) == 0 );
|
||||
assert( strcmp( s.c_str(), "abcde" ) != 0 ); </pre>
|
||||
|
||||
<p>The solution is surprisingly easy. The <a href="gotw29a.txt">original
|
||||
answer</a> was posted on Usenet, and a revised version appears in
|
||||
Herb Sutter's book <em>Exceptional C++</em> and on his website as
|
||||
<a href="http://www.gotw.ca/gotw/029.htm">GotW 29</a>.
|
||||
</p>
|
||||
<p>See? Told you it was easy!</p>
|
||||
<p><strong>Added June 2000:</strong> The May 2000 issue of <u>C++ Report</u>
|
||||
contains a fascinating <a href="http://lafstern.org/matt/col2_new.pdf">
|
||||
article</a> by Matt Austern (yes, <em>the</em> Matt Austern)
|
||||
on why case-insensitive comparisons are not as easy as they seem,
|
||||
and why creating a class is the <em>wrong</em> way to go about it in
|
||||
production code. (The GotW answer mentions one of the principle
|
||||
difficulties; his article mentions more.)
|
||||
</p>
|
||||
<p>Basically, this is "easy" only if you ignore some things,
|
||||
things which may be too important to your program to ignore. (I chose
|
||||
to ignore them when originally writing this entry, and am surprised
|
||||
that nobody ever called me on it...) The GotW question and answer
|
||||
remain useful instructional tools, however.
|
||||
</p>
|
||||
<p><strong>Added September 2000:</strong> James Kanze provided a link to a
|
||||
<a href="http://www.unicode.org/unicode/reports/tr21/">Unicode
|
||||
Technical Report discussing case handling</a>, which provides some
|
||||
very good information.
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="3">Breaking a C++ string into tokens</a></h2>
|
||||
<p>The Standard C (and C++) function <code>strtok()</code> leaves a lot to
|
||||
be desired in terms of user-friendliness. It's unintuitive, it
|
||||
destroys the character string on which it operates, and it requires
|
||||
you to handle all the memory problems. But it does let the client
|
||||
code decide what to use to break the string into pieces; it allows
|
||||
you to choose the "whitespace," so to speak.
|
||||
</p>
|
||||
<p>A C++ implementation lets us keep the good things and fix those
|
||||
annoyances. The implementation here is more intuitive (you only
|
||||
call it once, not in a loop with varying argument), it does not
|
||||
affect the original string at all, and all the memory allocation
|
||||
is handled for you.
|
||||
</p>
|
||||
<p>It's called stringtok, and it's a template function. It's given
|
||||
<a href="stringtok_h.txt">in this file</a> in a less-portable form than
|
||||
it could be, to keep this example simple (for example, see the
|
||||
comments on what kind of string it will accept). The author uses
|
||||
a more general (but less readable) form of it for parsing command
|
||||
strings and the like. If you compiled and ran this code using it:
|
||||
</p>
|
||||
<pre>
|
||||
std::list<string> ls;
|
||||
stringtok (ls, " this \t is\t\n a test ");
|
||||
for (std::list<string>const_iterator i = ls.begin();
|
||||
i != ls.end(); ++i)
|
||||
{
|
||||
std::cerr << ':' << (*i) << ":\n";
|
||||
} </pre>
|
||||
<p>You would see this as output:
|
||||
</p>
|
||||
<pre>
|
||||
:this:
|
||||
:is:
|
||||
:a:
|
||||
:test: </pre>
|
||||
<p>with all the whitespace removed. The original <code>s</code> is still
|
||||
available for use, <code>ls</code> will clean up after itself, and
|
||||
<code>ls.size()</code> will return how many tokens there were.
|
||||
</p>
|
||||
<p>As always, there is a price paid here, in that stringtok is not
|
||||
as fast as strtok. The other benefits usually outweigh that, however.
|
||||
<a href="stringtok_std_h.txt">Another version of stringtok is given
|
||||
here</a>, suggested by Chris King and tweaked by Petr Prikryl,
|
||||
and this one uses the
|
||||
transformation functions mentioned below. If you are comfortable
|
||||
with reading the new function names, this version is recommended
|
||||
as an example.
|
||||
</p>
|
||||
<p><strong>Added February 2001:</strong> Mark Wilden pointed out that the
|
||||
standard <code>std::getline()</code> function can be used with standard
|
||||
<a href="../27_io/howto.html">istringstreams</a> to perform
|
||||
tokenizing as well. Build an istringstream from the input text,
|
||||
and then use std::getline with varying delimiters (the three-argument
|
||||
signature) to extract tokens into a string.
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="4">Simple transformations</a></h2>
|
||||
<p>Here are Standard, simple, and portable ways to perform common
|
||||
transformations on a <code>string</code> instance, such as "convert
|
||||
to all upper case." The word transformations is especially
|
||||
apt, because the standard template function
|
||||
<code>transform<></code> is used.
|
||||
</p>
|
||||
<p>This code will go through some iterations (no pun). Here's the
|
||||
simplistic version usually seen on Usenet:
|
||||
</p>
|
||||
<pre>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <cctype> // old <ctype.h>
|
||||
|
||||
struct ToLower
|
||||
{
|
||||
char operator() (char c) const { return std::tolower(c); }
|
||||
};
|
||||
|
||||
struct ToUpper
|
||||
{
|
||||
char operator() (char c) const { return std::toupper(c); }
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
std::string s ("Some Kind Of Initial Input Goes Here");
|
||||
|
||||
// Change everything into upper case
|
||||
std::transform (s.begin(), s.end(), s.begin(), ToUpper());
|
||||
|
||||
// Change everything into lower case
|
||||
std::transform (s.begin(), s.end(), s.begin(), ToLower());
|
||||
|
||||
// Change everything back into upper case, but store the
|
||||
// result in a different string
|
||||
std::string capital_s;
|
||||
capital_s.resize(s.size());
|
||||
std::transform (s.begin(), s.end(), capital_s.begin(), ToUpper());
|
||||
} </pre>
|
||||
<p><span class="larger"><strong>Note</strong></span> that these calls all
|
||||
involve the global C locale through the use of the C functions
|
||||
<code>toupper/tolower</code>. This is absolutely guaranteed to work --
|
||||
but <em>only</em> if the string contains <em>only</em> characters
|
||||
from the basic source character set, and there are <em>only</em>
|
||||
96 of those. Which means that not even all English text can be
|
||||
represented (certain British spellings, proper names, and so forth).
|
||||
So, if all your input forevermore consists of only those 96
|
||||
characters (hahahahahaha), then you're done.
|
||||
</p>
|
||||
<p><span class="larger"><strong>Note</strong></span> that the
|
||||
<code>ToUpper</code> and <code>ToLower</code> function objects
|
||||
are needed because <code>toupper</code> and <code>tolower</code>
|
||||
are overloaded names (declared in <code><cctype></code> and
|
||||
<code><locale></code>) so the template-arguments for
|
||||
<code>transform<></code> cannot be deduced, as explained in
|
||||
<a href="http://gcc.gnu.org/ml/libstdc++/2002-11/msg00180.html">this
|
||||
message</a>. <!-- section 14.8.2.4 clause 16 in ISO 14882:1998
|
||||
if you're into that sort of thing -->
|
||||
At minimum, you can write short wrappers like
|
||||
</p>
|
||||
<pre>
|
||||
char toLower (char c)
|
||||
{
|
||||
return std::tolower(c);
|
||||
} </pre>
|
||||
<p>The correct method is to use a facet for a particular locale
|
||||
and call its conversion functions. These are discussed more in
|
||||
Chapter 22; the specific part is
|
||||
<a href="../22_locale/howto.html#7">Correct Transformations</a>,
|
||||
which shows the final version of this code. (Thanks to James Kanze
|
||||
for assistance and suggestions on all of this.)
|
||||
</p>
|
||||
<p>Another common operation is trimming off excess whitespace. Much
|
||||
like transformations, this task is trivial with the use of string's
|
||||
<code>find</code> family. These examples are broken into multiple
|
||||
statements for readability:
|
||||
</p>
|
||||
<pre>
|
||||
std::string str (" \t blah blah blah \n ");
|
||||
|
||||
// trim leading whitespace
|
||||
string::size_type notwhite = str.find_first_not_of(" \t\n");
|
||||
str.erase(0,notwhite);
|
||||
|
||||
// trim trailing whitespace
|
||||
notwhite = str.find_last_not_of(" \t\n");
|
||||
str.erase(notwhite+1); </pre>
|
||||
<p>Obviously, the calls to <code>find</code> could be inserted directly
|
||||
into the calls to <code>erase</code>, in case your compiler does not
|
||||
optimize named temporaries out of existence.
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="5">Making strings of arbitrary character types</a></h2>
|
||||
<p>The <code>std::basic_string</code> is tantalizingly general, in that
|
||||
it is parameterized on the type of the characters which it holds.
|
||||
In theory, you could whip up a Unicode character class and instantiate
|
||||
<code>std::basic_string<my_unicode_char></code>, or assuming
|
||||
that integers are wider than characters on your platform, maybe just
|
||||
declare variables of type <code>std::basic_string<int></code>.
|
||||
</p>
|
||||
<p>That's the theory. Remember however that basic_string has additional
|
||||
type parameters, which take default arguments based on the character
|
||||
type (called <code>CharT</code> here):
|
||||
</p>
|
||||
<pre>
|
||||
template <typename CharT,
|
||||
typename Traits = char_traits<CharT>,
|
||||
typename Alloc = allocator<CharT> >
|
||||
class basic_string { .... };</pre>
|
||||
<p>Now, <code>allocator<CharT></code> will probably Do The Right
|
||||
Thing by default, unless you need to implement your own allocator
|
||||
for your characters.
|
||||
</p>
|
||||
<p>But <code>char_traits</code> takes more work. The char_traits
|
||||
template is <em>declared</em> but not <em>defined</em>.
|
||||
That means there is only
|
||||
</p>
|
||||
<pre>
|
||||
template <typename CharT>
|
||||
struct char_traits
|
||||
{
|
||||
static void foo (type1 x, type2 y);
|
||||
...
|
||||
};</pre>
|
||||
<p>and functions such as char_traits<CharT>::foo() are not
|
||||
actually defined anywhere for the general case. The C++ standard
|
||||
permits this, because writing such a definition to fit all possible
|
||||
CharT's cannot be done.
|
||||
</p>
|
||||
<p>The C++ standard also requires that char_traits be specialized for
|
||||
instantiations of <code>char</code> and <code>wchar_t</code>, and it
|
||||
is these template specializations that permit entities like
|
||||
<code>basic_string<char,char_traits<char>></code> to work.
|
||||
</p>
|
||||
<p>If you want to use character types other than char and wchar_t,
|
||||
such as <code>unsigned char</code> and <code>int</code>, you will
|
||||
need suitable specializations for them. For a time, in earlier
|
||||
versions of GCC, there was a mostly-correct implementation that
|
||||
let programmers be lazy but it broke under many situations, so it
|
||||
was removed. GCC 3.4 introduced a new implementation that mostly
|
||||
works and can be specialized even for <code>int</code> and other
|
||||
built-in types.
|
||||
</p>
|
||||
<p>If you want to use your own special character class, then you have
|
||||
<a href="http://gcc.gnu.org/ml/libstdc++/2002-08/msg00163.html">a lot
|
||||
of work to do</a>, especially if you with to use i18n features
|
||||
(facets require traits information but don't have a traits argument).
|
||||
</p>
|
||||
<p>Another example of how to specialize char_traits was given <a
|
||||
href="http://gcc.gnu.org/ml/libstdc++/2002-08/msg00260.html">on the
|
||||
mailing list</a> and at a later date was put into the file <code>
|
||||
include/ext/pod_char_traits.h</code>. We agree
|
||||
that the way it's used with basic_string (scroll down to main())
|
||||
doesn't look nice, but that's because <a
|
||||
href="http://gcc.gnu.org/ml/libstdc++/2002-08/msg00236.html">the
|
||||
nice-looking first attempt</a> turned out to <a
|
||||
href="http://gcc.gnu.org/ml/libstdc++/2002-08/msg00242.html">not
|
||||
be conforming C++</a>, due to the rule that CharT must be a POD.
|
||||
(See how tricky this is?)
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="6">Shrink-to-fit strings</a></h2>
|
||||
<!-- referenced by faq/index.html#5_9, update link if numbering changes -->
|
||||
<p>From GCC 3.4 calling <code>s.reserve(res)</code> on a
|
||||
<code>string s</code> with <code>res < s.capacity()</code> will
|
||||
reduce the string's capacity to <code>std::max(s.size(), res)</code>.
|
||||
</p>
|
||||
<p>This behaviour is suggested, but not required by the standard. Prior
|
||||
to GCC 3.4 the following alternative can be used instead
|
||||
</p>
|
||||
<pre>
|
||||
std::string(str.data(), str.size()).swap(str);
|
||||
</pre>
|
||||
<p>This is similar to the idiom for reducing a <code>vector</code>'s
|
||||
memory usage (see <a href='../faq/index.html#5_9'>FAQ 5.9</a>) but
|
||||
the regular copy constructor cannot be used because libstdc++'s
|
||||
<code>string</code> is Copy-On-Write.
|
||||
</p>
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<hr />
|
||||
<p class="fineprint"><em>
|
||||
See <a href="../17_intro/license.html">license.html</a> for copying conditions.
|
||||
Comments and suggestions are welcome, and may be sent to
|
||||
<a href="mailto:libstdc++@gcc.gnu.org">the libstdc++ mailing list</a>.
|
||||
</em></p>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,102 +0,0 @@
|
|||
/*
|
||||
* stringtok.h -- Breaks a string into tokens. This is an example for lib3.
|
||||
*
|
||||
* Template function looks like this:
|
||||
*
|
||||
* template <typename Container>
|
||||
* void stringtok (Container &l,
|
||||
* string const &s,
|
||||
* char const * const ws = " \t\n");
|
||||
*
|
||||
* A nondestructive version of strtok() that handles its own memory and can
|
||||
* be broken up by any character(s). Does all the work at once rather than
|
||||
* in an invocation loop like strtok() requires.
|
||||
*
|
||||
* Container is any type that supports push_back(a_string), although using
|
||||
* list<string> and deque<string> are indicated due to their O(1) push_back.
|
||||
* (I prefer deque<> because op[]/at() is available as well.) The first
|
||||
* parameter references an existing Container.
|
||||
*
|
||||
* s is the string to be tokenized. From the parameter declaration, it can
|
||||
* be seen that s is not affected. Since references-to-const may refer to
|
||||
* temporaries, you could use stringtok(some_container, readline("")) when
|
||||
* using the GNU readline library.
|
||||
*
|
||||
* The final parameter is an array of characters that serve as whitespace.
|
||||
* Whitespace characters default to one or more of tab, space, and newline,
|
||||
* in any combination.
|
||||
*
|
||||
* 'l' need not be empty on entry. On return, 'l' will have the token
|
||||
* strings appended.
|
||||
*
|
||||
*
|
||||
* [Example:
|
||||
* list<string> ls;
|
||||
* stringtok (ls, " this \t is\t\n a test ");
|
||||
* for (list<string>::const_iterator i = ls.begin();
|
||||
* i != ls.end(); ++i)
|
||||
* {
|
||||
* cerr << ':' << (*i) << ":\n";
|
||||
* }
|
||||
*
|
||||
* would print
|
||||
* :this:
|
||||
* :is:
|
||||
* :a:
|
||||
* :test:
|
||||
* -end example]
|
||||
*
|
||||
* pedwards@jaj.com May 1999
|
||||
*/
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <cstring> // for strchr
|
||||
|
||||
|
||||
/*****************************************************************
|
||||
* This is the only part of the implementation that I don't like.
|
||||
* It can probably be improved upon by the reader...
|
||||
*/
|
||||
namespace {
|
||||
inline bool
|
||||
isws (char c, char const * const wstr)
|
||||
{
|
||||
return (strchr(wstr,c) != NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************
|
||||
* Simplistic and quite Standard, but a bit slow. This should be
|
||||
* templatized on basic_string instead, or on a more generic StringT
|
||||
* that just happens to support ::size_type, .substr(), and so on.
|
||||
* I had hoped that "whitespace" would be a trait, but it isn't, so
|
||||
* the user must supply it. Enh, this lets them break up strings on
|
||||
* different things easier than traits would anyhow.
|
||||
*/
|
||||
template <typename Container>
|
||||
void
|
||||
stringtok (Container &l, string const &s, char const * const ws = " \t\n")
|
||||
{
|
||||
const string::size_type S = s.size();
|
||||
string::size_type i = 0;
|
||||
|
||||
while (i < S) {
|
||||
// eat leading whitespace
|
||||
while ((i < S) && (isws(s[i],ws))) ++i;
|
||||
if (i == S) return; // nothing left but WS
|
||||
|
||||
// find end of word
|
||||
string::size_type j = i+1;
|
||||
while ((j < S) && (!isws(s[j],ws))) ++j;
|
||||
|
||||
// add word
|
||||
l.push_back(s.substr(i,j-i));
|
||||
|
||||
// set up for next loop
|
||||
i = j+1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* Same as stringtok_h.txt, but doesn't (visiably) use C functions.
|
||||
*/
|
||||
|
||||
#include <string>
|
||||
|
||||
// The std:: prefix is not used here, for readability, and a line like
|
||||
// "using namespace std;" is dangerous to have in a header file.
|
||||
|
||||
template <typename Container>
|
||||
void
|
||||
stringtok (Container &container, string const &in,
|
||||
const char * const delimiters = " \t\n")
|
||||
{
|
||||
const string::size_type len = in.length();
|
||||
string::size_type i = 0;
|
||||
|
||||
while ( i < len )
|
||||
{
|
||||
// eat leading whitespace
|
||||
i = in.find_first_not_of (delimiters, i);
|
||||
if (i == string::npos)
|
||||
return; // nothing left but white space
|
||||
|
||||
// find the end of the token
|
||||
string::size_type j = in.find_first_of (delimiters, i);
|
||||
|
||||
// push token
|
||||
if (j == string::npos) {
|
||||
container.push_back (in.substr(i));
|
||||
return;
|
||||
} else
|
||||
container.push_back (in.substr(i, j-i));
|
||||
|
||||
// set up for next loop
|
||||
i = j + 1;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,595 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta name="AUTHOR" content="bkoz@redhat.com (Benjamin Kosnik)" />
|
||||
<meta name="KEYWORDS" content="HOWTO, libstdc++, GCC, g++, libg++, STL" />
|
||||
<meta name="DESCRIPTION" content="Notes on the codecvt implementation." />
|
||||
<title>Notes on the codecvt implementation.</title>
|
||||
<link rel="StyleSheet" href="../lib3styles.css" type="text/css" />
|
||||
<link rel="Start" href="../documentation.html" type="text/html"
|
||||
title="GNU C++ Standard Library" />
|
||||
<link rel="Bookmark" href="howto.html" type="text/html" title="Localization" />
|
||||
<link rel="Copyright" href="../17_intro/license.html" type="text/html" />
|
||||
<link rel="Help" href="../faq/index.html" type="text/html" title="F.A.Q." />
|
||||
</head>
|
||||
<body>
|
||||
<h1>
|
||||
Notes on the codecvt implementation.
|
||||
</h1>
|
||||
<p>
|
||||
<em>
|
||||
prepared by Benjamin Kosnik (bkoz@redhat.com) on August 28, 2000
|
||||
</em>
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
1. Abstract
|
||||
</h2>
|
||||
<p>
|
||||
The standard class codecvt attempts to address conversions between
|
||||
different character encoding schemes. In particular, the standard
|
||||
attempts to detail conversions between the implementation-defined wide
|
||||
characters (hereafter referred to as wchar_t) and the standard type
|
||||
char that is so beloved in classic "C" (which can now be referred to
|
||||
as narrow characters.) This document attempts to describe how the GNU
|
||||
libstdc++ implementation deals with the conversion between wide and
|
||||
narrow characters, and also presents a framework for dealing with the
|
||||
huge number of other encodings that iconv can convert, including
|
||||
Unicode and UTF8. Design issues and requirements are addressed, and
|
||||
examples of correct usage for both the required specializations for
|
||||
wide and narrow characters and the implementation-provided extended
|
||||
functionality are given.
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
2. What the standard says
|
||||
</h2>
|
||||
Around page 425 of the C++ Standard, this charming heading comes into view:
|
||||
|
||||
<blockquote>
|
||||
22.2.1.5 - Template class codecvt [lib.locale.codecvt]
|
||||
</blockquote>
|
||||
|
||||
The text around the codecvt definition gives some clues:
|
||||
|
||||
<blockquote>
|
||||
<em>
|
||||
-1- The class codecvt<internT,externT,stateT> is for use when
|
||||
converting from one codeset to another, such as from wide characters
|
||||
to multibyte characters, between wide character encodings such as
|
||||
Unicode and EUC.
|
||||
</em>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
Hmm. So, in some unspecified way, Unicode encodings and
|
||||
translations between other character sets should be handled by this
|
||||
class.
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
<em>
|
||||
-2- The stateT argument selects the pair of codesets being mapped between.
|
||||
</em>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
Ah ha! Another clue...
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
<em>
|
||||
-3- The instantiations required in the Table ??
|
||||
(lib.locale.category), namely codecvt<wchar_t,char,mbstate_t> and
|
||||
codecvt<char,char,mbstate_t>, convert the implementation-defined
|
||||
native character set. codecvt<char,char,mbstate_t> implements a
|
||||
degenerate conversion; it does not convert at
|
||||
all. codecvt<wchar_t,char,mbstate_t> converts between the native
|
||||
character sets for tiny and wide characters. Instantiations on
|
||||
mbstate_t perform conversion between encodings known to the library
|
||||
implementor. Other encodings can be converted by specializing on a
|
||||
user-defined stateT type. The stateT object can contain any state that
|
||||
is useful to communicate to or from the specialized do_convert member.
|
||||
</em>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
At this point, a couple points become clear:
|
||||
</p>
|
||||
|
||||
<p>
|
||||
One: The standard clearly implies that attempts to add non-required
|
||||
(yet useful and widely used) conversions need to do so through the
|
||||
third template parameter, stateT.</p>
|
||||
|
||||
<p>
|
||||
Two: The required conversions, by specifying mbstate_t as the third
|
||||
template parameter, imply an implementation strategy that is mostly
|
||||
(or wholly) based on the underlying C library, and the functions
|
||||
mcsrtombs and wcsrtombs in particular.</p>
|
||||
|
||||
<h2>
|
||||
3. Some thoughts on what would be useful
|
||||
</h2>
|
||||
Probably the most frequently asked question about code conversion is:
|
||||
"So dudes, what's the deal with Unicode strings?" The dude part is
|
||||
optional, but apparently the usefulness of Unicode strings is pretty
|
||||
widely appreciated. Sadly, this specific encoding (And other useful
|
||||
encodings like UTF8, UCS4, ISO 8859-10, etc etc etc) are not mentioned
|
||||
in the C++ standard.
|
||||
|
||||
<p>
|
||||
In particular, the simple implementation detail of wchar_t's size
|
||||
seems to repeatedly confound people. Many systems use a two byte,
|
||||
unsigned integral type to represent wide characters, and use an
|
||||
internal encoding of Unicode or UCS2. (See AIX, Microsoft NT, Java,
|
||||
others.) Other systems, use a four byte, unsigned integral type to
|
||||
represent wide characters, and use an internal encoding of
|
||||
UCS4. (GNU/Linux systems using glibc, in particular.) The C
|
||||
programming language (and thus C++) does not specify a specific size
|
||||
for the type wchar_t.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Thus, portable C++ code cannot assume a byte size (or endianness) either.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Getting back to the frequently asked question: What about Unicode strings?
|
||||
</p>
|
||||
|
||||
<p>
|
||||
What magic spell will do this conversion?
|
||||
</p>
|
||||
|
||||
<p>
|
||||
A couple of comments:
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The thought that all one needs to convert between two arbitrary
|
||||
codesets is two types and some kind of state argument is
|
||||
unfortunate. In particular, encodings may be stateless. The naming of
|
||||
the third parameter as stateT is unfortunate, as what is really needed
|
||||
is some kind of generalized type that accounts for the issues that
|
||||
abstract encodings will need. The minimum information that is required
|
||||
includes:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<p>
|
||||
Identifiers for each of the codesets involved in the conversion. For
|
||||
example, using the iconv family of functions from the Single Unix
|
||||
Specification (what used to be called X/Open) hosted on the GNU/Linux
|
||||
operating system allows bi-directional mapping between far more than
|
||||
the following tantalizing possibilities:
|
||||
</p>
|
||||
|
||||
<p>
|
||||
(An edited list taken from <code>`iconv --list`</code> on a Red Hat 6.2/Intel system:
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
8859_1, 8859_9, 10646-1:1993, 10646-1:1993/UCS4, ARABIC, ARABIC7,
|
||||
ASCII, EUC-CN, EUC-JP, EUC-KR, EUC-TW, GREEK-CCIcode, GREEK, GREEK7-OLD,
|
||||
GREEK7, GREEK8, HEBREW, ISO-8859-1, ISO-8859-2, ISO-8859-3,
|
||||
ISO-8859-4, ISO-8859-5, ISO-8859-6, ISO-8859-7, ISO-8859-8,
|
||||
ISO-8859-9, ISO-8859-10, ISO-8859-11, ISO-8859-13, ISO-8859-14,
|
||||
ISO-8859-15, ISO-10646, ISO-10646/UCS2, ISO-10646/UCS4,
|
||||
ISO-10646/UTF-8, ISO-10646/UTF8, SHIFT-JIS, SHIFT_JIS, UCS-2, UCS-4,
|
||||
UCS2, UCS4, UNICODE, UNICODEBIG, UNICODELIcodeLE, US-ASCII, US, UTF-8,
|
||||
UTF-16, UTF8, UTF16).
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
For iconv-based implementations, string literals for each of the
|
||||
encodings (ie. "UCS-2" and "UTF-8") are necessary,
|
||||
although for other,
|
||||
non-iconv implementations a table of enumerated values or some other
|
||||
mechanism may be required.
|
||||
</p>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
Maximum length of the identifying string literal.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
Some encodings require explicit endian-ness. As such, some kind
|
||||
of endian marker or other byte-order marker will be necessary. See
|
||||
"Footnotes for C/C++ developers" in Haible for more information on
|
||||
UCS-2/Unicode endian issues. (Summary: big endian seems most likely,
|
||||
however implementations, most notably Microsoft, vary.)
|
||||
</li>
|
||||
|
||||
<li>
|
||||
Types representing the conversion state, for conversions involving
|
||||
the machinery in the "C" library, or the conversion descriptor, for
|
||||
conversions using iconv (such as the type iconv_t.) Note that the
|
||||
conversion descriptor encodes more information than a simple encoding
|
||||
state type.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
Conversion descriptors for both directions of encoding. (ie, both
|
||||
UCS-2 to UTF-8 and UTF-8 to UCS-2.)
|
||||
</li>
|
||||
|
||||
<li>
|
||||
Something to indicate if the conversion requested if valid.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
Something to represent if the conversion descriptors are valid.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
Some way to enforce strict type checking on the internal and
|
||||
external types. As part of this, the size of the internal and
|
||||
external types will need to be known.
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
4. Problems with "C" code conversions : thread safety, global
|
||||
locales, termination.
|
||||
</h2>
|
||||
|
||||
In addition, multi-threaded and multi-locale environments also impact
|
||||
the design and requirements for code conversions. In particular, they
|
||||
affect the required specialization codecvt<wchar_t, char, mbstate_t>
|
||||
when implemented using standard "C" functions.
|
||||
|
||||
<p>
|
||||
Three problems arise, one big, one of medium importance, and one small.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
First, the small: mcsrtombs and wcsrtombs may not be multithread-safe
|
||||
on all systems required by the GNU tools. For GNU/Linux and glibc,
|
||||
this is not an issue.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Of medium concern, in the grand scope of things, is that the functions
|
||||
used to implement this specialization work on null-terminated
|
||||
strings. Buffers, especially file buffers, may not be null-terminated,
|
||||
thus giving conversions that end prematurely or are otherwise
|
||||
incorrect. Yikes!
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The last, and fundamental problem, is the assumption of a global
|
||||
locale for all the "C" functions referenced above. For something like
|
||||
C++ iostreams (where codecvt is explicitly used) the notion of
|
||||
multiple locales is fundamental. In practice, most users may not run
|
||||
into this limitation. However, as a quality of implementation issue,
|
||||
the GNU C++ library would like to offer a solution that allows
|
||||
multiple locales and or simultaneous usage with computationally
|
||||
correct results. In short, libstdc++ is trying to offer, as an
|
||||
option, a high-quality implementation, damn the additional complexity!
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For the required specialization codecvt<wchar_t, char, mbstate_t> ,
|
||||
conversions are made between the internal character set (always UCS4
|
||||
on GNU/Linux) and whatever the currently selected locale for the
|
||||
LC_CTYPE category implements.
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
5. Design
|
||||
</h2>
|
||||
The two required specializations are implemented as follows:
|
||||
|
||||
<p>
|
||||
<code>
|
||||
codecvt<char, char, mbstate_t>
|
||||
</code>
|
||||
</p>
|
||||
<p>
|
||||
This is a degenerate (ie, does nothing) specialization. Implementing
|
||||
this was a piece of cake.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<code>
|
||||
codecvt<char, wchar_t, mbstate_t>
|
||||
</code>
|
||||
</p>
|
||||
<p>
|
||||
This specialization, by specifying all the template parameters, pretty
|
||||
much ties the hands of implementors. As such, the implementation is
|
||||
straightforward, involving mcsrtombs for the conversions between char
|
||||
to wchar_t and wcsrtombs for conversions between wchar_t and char.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Neither of these two required specializations deals with Unicode
|
||||
characters. As such, libstdc++ implements a partial specialization
|
||||
of the codecvt class with and iconv wrapper class, encoding_state as the
|
||||
third template parameter.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
This implementation should be standards conformant. First of all, the
|
||||
standard explicitly points out that instantiations on the third
|
||||
template parameter, stateT, are the proper way to implement
|
||||
non-required conversions. Second of all, the standard says (in Chapter
|
||||
17) that partial specializations of required classes are a-ok. Third
|
||||
of all, the requirements for the stateT type elsewhere in the standard
|
||||
(see 21.1.2 traits typedefs) only indicate that this type be copy
|
||||
constructible.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
As such, the type encoding_state is defined as a non-templatized, POD
|
||||
type to be used as the third type of a codecvt instantiation. This
|
||||
type is just a wrapper class for iconv, and provides an easy interface
|
||||
to iconv functionality.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
There are two constructors for encoding_state:
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<code>
|
||||
encoding_state() : __in_desc(0), __out_desc(0)
|
||||
</code>
|
||||
</p>
|
||||
<p>
|
||||
This default constructor sets the internal encoding to some default
|
||||
(currently UCS4) and the external encoding to whatever is returned by
|
||||
nl_langinfo(CODESET).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<code>
|
||||
encoding_state(const char* __int, const char* __ext)
|
||||
</code>
|
||||
</p>
|
||||
<p>
|
||||
This constructor takes as parameters string literals that indicate the
|
||||
desired internal and external encoding. There are no defaults for
|
||||
either argument.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
One of the issues with iconv is that the string literals identifying
|
||||
conversions are not standardized. Because of this, the thought of
|
||||
mandating and or enforcing some set of pre-determined valid
|
||||
identifiers seems iffy: thus, a more practical (and non-migraine
|
||||
inducing) strategy was implemented: end-users can specify any string
|
||||
(subject to a pre-determined length qualifier, currently 32 bytes) for
|
||||
encodings. It is up to the user to make sure that these strings are
|
||||
valid on the target system.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<code>
|
||||
void
|
||||
_M_init()
|
||||
</code>
|
||||
</p>
|
||||
<p>
|
||||
Strangely enough, this member function attempts to open conversion
|
||||
descriptors for a given encoding_state object. If the conversion
|
||||
descriptors are not valid, the conversion descriptors returned will
|
||||
not be valid and the resulting calls to the codecvt conversion
|
||||
functions will return error.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<code>
|
||||
bool
|
||||
_M_good()
|
||||
</code>
|
||||
</p>
|
||||
<p>
|
||||
Provides a way to see if the given encoding_state object has been
|
||||
properly initialized. If the string literals describing the desired
|
||||
internal and external encoding are not valid, initialization will
|
||||
fail, and this will return false. If the internal and external
|
||||
encodings are valid, but iconv_open could not allocate conversion
|
||||
descriptors, this will also return false. Otherwise, the object is
|
||||
ready to convert and will return true.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<code>
|
||||
encoding_state(const encoding_state&)
|
||||
</code>
|
||||
</p>
|
||||
<p>
|
||||
As iconv allocates memory and sets up conversion descriptors, the copy
|
||||
constructor can only copy the member data pertaining to the internal
|
||||
and external code conversions, and not the conversion descriptors
|
||||
themselves.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Definitions for all the required codecvt member functions are provided
|
||||
for this specialization, and usage of codecvt<internal character type,
|
||||
external character type, encoding_state> is consistent with other
|
||||
codecvt usage.
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
6. Examples
|
||||
</h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
a. conversions involving string literals
|
||||
|
||||
<pre>
|
||||
typedef codecvt_base::result result;
|
||||
typedef unsigned short unicode_t;
|
||||
typedef unicode_t int_type;
|
||||
typedef char ext_type;
|
||||
typedef encoding_state state_type;
|
||||
typedef codecvt<int_type, ext_type, state_type> unicode_codecvt;
|
||||
|
||||
const ext_type* e_lit = "black pearl jasmine tea";
|
||||
int size = strlen(e_lit);
|
||||
int_type i_lit_base[24] =
|
||||
{ 25088, 27648, 24832, 25344, 27392, 8192, 28672, 25856, 24832, 29184,
|
||||
27648, 8192, 27136, 24832, 29440, 27904, 26880, 28160, 25856, 8192, 29696,
|
||||
25856, 24832, 2560
|
||||
};
|
||||
const int_type* i_lit = i_lit_base;
|
||||
const ext_type* efrom_next;
|
||||
const int_type* ifrom_next;
|
||||
ext_type* e_arr = new ext_type[size + 1];
|
||||
ext_type* eto_next;
|
||||
int_type* i_arr = new int_type[size + 1];
|
||||
int_type* ito_next;
|
||||
|
||||
// construct a locale object with the specialized facet.
|
||||
locale loc(locale::classic(), new unicode_codecvt);
|
||||
// sanity check the constructed locale has the specialized facet.
|
||||
VERIFY( has_facet<unicode_codecvt>(loc) );
|
||||
const unicode_codecvt& cvt = use_facet<unicode_codecvt>(loc);
|
||||
// convert between const char* and unicode strings
|
||||
unicode_codecvt::state_type state01("UNICODE", "ISO_8859-1");
|
||||
initialize_state(state01);
|
||||
result r1 = cvt.in(state01, e_lit, e_lit + size, efrom_next,
|
||||
i_arr, i_arr + size, ito_next);
|
||||
VERIFY( r1 == codecvt_base::ok );
|
||||
VERIFY( !int_traits::compare(i_arr, i_lit, size) );
|
||||
VERIFY( efrom_next == e_lit + size );
|
||||
VERIFY( ito_next == i_arr + size );
|
||||
</pre>
|
||||
</li>
|
||||
<li>
|
||||
b. conversions involving std::string
|
||||
</li>
|
||||
<li>
|
||||
c. conversions involving std::filebuf and std::ostream
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
More information can be found in the following testcases:
|
||||
<ul>
|
||||
<li> testsuite/22_locale/codecvt_char_char.cc </li>
|
||||
<li> testsuite/22_locale/codecvt_unicode_wchar_t.cc </li>
|
||||
<li> testsuite/22_locale/codecvt_unicode_char.cc </li>
|
||||
<li> testsuite/22_locale/codecvt_wchar_t_char.cc </li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
7. Unresolved Issues
|
||||
</h2>
|
||||
<ul>
|
||||
<li>
|
||||
a. things that are sketchy, or remain unimplemented:
|
||||
do_encoding, max_length and length member functions
|
||||
are only weakly implemented. I have no idea how to do
|
||||
this correctly, and in a generic manner. Nathan?
|
||||
</li>
|
||||
|
||||
<li>
|
||||
b. conversions involving std::string
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
how should operators != and == work for string of
|
||||
different/same encoding?
|
||||
</li>
|
||||
|
||||
<li>
|
||||
what is equal? A byte by byte comparison or an
|
||||
encoding then byte comparison?
|
||||
</li>
|
||||
|
||||
<li>
|
||||
conversions between narrow, wide, and unicode strings
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>
|
||||
c. conversions involving std::filebuf and std::ostream
|
||||
<ul>
|
||||
<li>
|
||||
how to initialize the state object in a
|
||||
standards-conformant manner?
|
||||
</li>
|
||||
|
||||
<li>
|
||||
how to synchronize the "C" and "C++"
|
||||
conversion information?
|
||||
</li>
|
||||
|
||||
<li>
|
||||
wchar_t/char internal buffers and conversions between
|
||||
internal/external buffers?
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
8. Acknowledgments
|
||||
</h2>
|
||||
Ulrich Drepper for the iconv suggestions and patient answering of
|
||||
late-night questions, Jason Merrill for the template partial
|
||||
specialization hints, language clarification, and wchar_t fixes.
|
||||
|
||||
<h2>
|
||||
9. Bibliography / Referenced Documents
|
||||
</h2>
|
||||
|
||||
Drepper, Ulrich, GNU libc (glibc) 2.2 manual. In particular, Chapters "6. Character Set Handling" and "7 Locales and Internationalization"
|
||||
|
||||
<p>
|
||||
Drepper, Ulrich, Numerous, late-night email correspondence
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Feather, Clive, "A brief description of Normative Addendum 1," in particular the parts on Extended Character Sets
|
||||
http://www.lysator.liu.se/c/na1.html
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Haible, Bruno, "The Unicode HOWTO" v0.18, 4 August 2000
|
||||
ftp://ftp.ilog.fr/pub/Users/haible/utf8/Unicode-HOWTO.html
|
||||
</p>
|
||||
|
||||
<p>
|
||||
ISO/IEC 14882:1998 Programming languages - C++
|
||||
</p>
|
||||
|
||||
<p>
|
||||
ISO/IEC 9899:1999 Programming languages - C
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Khun, Markus, "UTF-8 and Unicode FAQ for Unix/Linux"
|
||||
http://www.cl.cam.ac.uk/~mgk25/unicode.html
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Langer, Angelika and Klaus Kreft, Standard C++ IOStreams and Locales, Advanced Programmer's Guide and Reference, Addison Wesley Longman, Inc. 2000
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Stroustrup, Bjarne, Appendix D, The C++ Programming Language, Special Edition, Addison Wesley, Inc. 2000
|
||||
</p>
|
||||
|
||||
<p>
|
||||
System Interface Definitions, Issue 6 (IEEE Std. 1003.1-200x)
|
||||
The Open Group/The Institute of Electrical and Electronics Engineers, Inc.
|
||||
http://www.opennc.org/austin/docreg.html
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,166 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta name="AUTHOR" content="bkoz@redhat.com (Benjamin Kosnik)" />
|
||||
<meta name="KEYWORDS" content="HOWTO, libstdc++, GCC, g++, libg++, STL" />
|
||||
<meta name="DESCRIPTION" content="Notes on the ctype implementation." />
|
||||
<title>Notes on the ctype implementation.</title>
|
||||
<link rel="StyleSheet" href="../lib3styles.css" type="text/css" />
|
||||
<link rel="Start" href="../documentation.html" type="text/html"
|
||||
title="GNU C++ Standard Library" />
|
||||
<link rel="Bookmark" href="howto.html" type="text/html" title="Localization" />
|
||||
<link rel="Copyright" href="../17_intro/license.html" type="text/html" />
|
||||
<link rel="Help" href="../faq/index.html" type="text/html" title="F.A.Q." />
|
||||
</head>
|
||||
<body>
|
||||
<h1>
|
||||
Notes on the ctype implementation.
|
||||
</h1>
|
||||
<em>
|
||||
prepared by Benjamin Kosnik (bkoz@redhat.com) on August 30, 2000
|
||||
</em>
|
||||
|
||||
<h2>
|
||||
1. Abstract
|
||||
</h2>
|
||||
<p>
|
||||
Woe is me.
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
2. What the standard says
|
||||
</h2>
|
||||
|
||||
|
||||
<h2>
|
||||
3. Problems with "C" ctype : global locales, termination.
|
||||
</h2>
|
||||
|
||||
<p>
|
||||
For the required specialization codecvt<wchar_t, char, mbstate_t> ,
|
||||
conversions are made between the internal character set (always UCS4
|
||||
on GNU/Linux) and whatever the currently selected locale for the
|
||||
LC_CTYPE category implements.
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
4. Design
|
||||
</h2>
|
||||
The two required specializations are implemented as follows:
|
||||
|
||||
<p>
|
||||
<code>
|
||||
ctype<char>
|
||||
</code>
|
||||
</p>
|
||||
<p>
|
||||
This is simple specialization. Implementing this was a piece of cake.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<code>
|
||||
ctype<wchar_t>
|
||||
</code>
|
||||
</p>
|
||||
<p>
|
||||
This specialization, by specifying all the template parameters, pretty
|
||||
much ties the hands of implementors. As such, the implementation is
|
||||
straightforward, involving mcsrtombs for the conversions between char
|
||||
to wchar_t and wcsrtombs for conversions between wchar_t and char.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Neither of these two required specializations deals with Unicode
|
||||
characters. As such, libstdc++ implements
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
5. Examples
|
||||
</h2>
|
||||
|
||||
<pre>
|
||||
typedef ctype<char> cctype;
|
||||
</pre>
|
||||
|
||||
More information can be found in the following testcases:
|
||||
<ul>
|
||||
<li> testsuite/22_locale/ctype_char_members.cc </li>
|
||||
<li> testsuite/22_locale/ctype_wchar_t_members.cc </li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
6. Unresolved Issues
|
||||
</h2>
|
||||
|
||||
<ul>
|
||||
<li> how to deal with the global locale issue? </li>
|
||||
|
||||
<li> how to deal with different types than char, wchar_t? </li>
|
||||
|
||||
<li> codecvt/ctype overlap: narrow/widen </li>
|
||||
|
||||
<li> mask typedef in codecvt_base, argument types in codecvt.
|
||||
what is know about this type? </li>
|
||||
|
||||
<li> why mask* argument in codecvt? </li>
|
||||
|
||||
<li> can this be made (more) generic? is there a simple way to
|
||||
straighten out the configure-time mess that is a by-product of
|
||||
this class? </li>
|
||||
|
||||
<li> get the ctype<wchar_t>::mask stuff under control. Need to
|
||||
make some kind of static table, and not do lookup evertime
|
||||
somebody hits the do_is... functions. Too bad we can't just
|
||||
redefine mask for ctype<wchar_t> </li>
|
||||
|
||||
<li> rename abstract base class. See if just smash-overriding
|
||||
is a better approach. Clarify, add sanity to naming. </li>
|
||||
|
||||
</ul>
|
||||
|
||||
|
||||
<h2>
|
||||
7. Acknowledgments
|
||||
</h2>
|
||||
Ulrich Drepper for patient answering of late-night questions, skeletal
|
||||
examples, and C language expertise.
|
||||
|
||||
<h2>
|
||||
8. Bibliography / Referenced Documents
|
||||
</h2>
|
||||
|
||||
Drepper, Ulrich, GNU libc (glibc) 2.2 manual. In particular, Chapters "6. Character Set Handling" and "7 Locales and Internationalization"
|
||||
|
||||
<p>
|
||||
Drepper, Ulrich, Numerous, late-night email correspondence
|
||||
</p>
|
||||
|
||||
<p>
|
||||
ISO/IEC 14882:1998 Programming languages - C++
|
||||
</p>
|
||||
|
||||
<p>
|
||||
ISO/IEC 9899:1999 Programming languages - C
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Langer, Angelika and Klaus Kreft, Standard C++ IOStreams and Locales, Advanced Programmer's Guide and Reference, Addison Wesley Longman, Inc. 2000
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Stroustrup, Bjarne, Appendix D, The C++ Programming Language, Special Edition, Addison Wesley, Inc. 2000
|
||||
</p>
|
||||
|
||||
<p>
|
||||
System Interface Definitions, Issue 6 (IEEE Std. 1003.1-200x)
|
||||
The Open Group/The Institute of Electrical and Electronics Engineers, Inc.
|
||||
http://www.opennc.org/austin/docreg.html
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,240 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta name="AUTHOR" content="pme@gcc.gnu.org (Phil Edwards)" />
|
||||
<meta name="KEYWORDS" content="HOWTO, libstdc++, GCC, g++, libg++, STL" />
|
||||
<meta name="DESCRIPTION" content="HOWTO for the libstdc++ chapter 22." />
|
||||
<meta name="GENERATOR" content="vi and eight fingers" />
|
||||
<title>libstdc++ HOWTO: Chapter 22: Localization</title>
|
||||
<link rel="StyleSheet" href="../lib3styles.css" type="text/css" />
|
||||
<link rel="Start" href="../documentation.html" type="text/html"
|
||||
title="GNU C++ Standard Library" />
|
||||
<link rel="Prev" href="../21_strings/howto.html" type="text/html"
|
||||
title="Strings" />
|
||||
<link rel="Next" href="../23_containers/howto.html" type="text/html"
|
||||
title="Containers" />
|
||||
<link rel="Bookmark" href="locale.html" type="text/html" title="class locale" />
|
||||
<link rel="Bookmark" href="codecvt.html" type="text/html" title="class codecvt" />
|
||||
<link rel="Bookmark" href="ctype.html" type="text/html" title="class ctype" />
|
||||
<link rel="Bookmark" href="messages.html" type="text/html" title="class messages" />
|
||||
<link rel="Bookmark" href="http://www.research.att.com/~bs/3rd_loc0.html" type="text/html" title="Bjarne Stroustrup on Locales" />
|
||||
<link rel="Bookmark" href="http://www.cantrip.org/locale.html" type="text/html" title="Nathan Myers on Locales" />
|
||||
<link rel="Copyright" href="../17_intro/license.html" type="text/html" />
|
||||
<link rel="Help" href="../faq/index.html" type="text/html" title="F.A.Q." />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 class="centered"><a name="top">Chapter 22: Localization</a></h1>
|
||||
|
||||
<p>Chapter 22 deals with the C++ localization facilities.
|
||||
</p>
|
||||
<!-- I wanted to write that sentence in something requiring an exotic font,
|
||||
like Cyrllic or Kanji. Probably more work than such cuteness is worth,
|
||||
but I still think it'd be funny.
|
||||
-->
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
<hr />
|
||||
<h1>Contents</h1>
|
||||
<ul>
|
||||
<li><a href="#1">class locale</a></li>
|
||||
<li><a href="#2">class codecvt</a></li>
|
||||
<li><a href="#3">class ctype</a></li>
|
||||
<li><a href="#4">class messages</a></li>
|
||||
<li><a href="#5">Bjarne Stroustrup on Locales</a></li>
|
||||
<li><a href="#6">Nathan Myers on Locales</a></li>
|
||||
<li><a href="#7">Correct Transformations</a></li>
|
||||
</ul>
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<hr />
|
||||
<h2><a name="1">class locale</a></h2>
|
||||
<p>Notes made during the implementation of locales can be found
|
||||
<a href="locale.html">here</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="2">class codecvt</a></h2>
|
||||
<p>Notes made during the implementation of codecvt can be found
|
||||
<a href="codecvt.html">here</a>.
|
||||
</p>
|
||||
|
||||
<p>The following is the abstract from the implementation notes:
|
||||
</p>
|
||||
<blockquote>
|
||||
The standard class codecvt attempts to address conversions between
|
||||
different character encoding schemes. In particular, the standard
|
||||
attempts to detail conversions between the implementation-defined
|
||||
wide characters (hereafter referred to as wchar_t) and the standard
|
||||
type char that is so beloved in classic "C" (which can
|
||||
now be referred to as narrow characters.) This document attempts
|
||||
to describe how the GNU libstdc++ implementation deals with the
|
||||
conversion between wide and narrow characters, and also presents a
|
||||
framework for dealing with the huge number of other encodings that
|
||||
iconv can convert, including Unicode and UTF8. Design issues and
|
||||
requirements are addressed, and examples of correct usage for both
|
||||
the required specializations for wide and narrow characters and the
|
||||
implementation-provided extended functionality are given.
|
||||
</blockquote>
|
||||
|
||||
<hr />
|
||||
<h2><a name="3">class ctype</a></h2>
|
||||
<p>Notes made during the implementation of ctype can be found
|
||||
<a href="ctype.html">here</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="4">class messages</a></h2>
|
||||
<p>Notes made during the implementation of messages can be found
|
||||
<a href="messages.html">here</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="5">Bjarne Stroustrup on Locales</a></h2>
|
||||
<p>Dr. Bjarne Stroustrup has released a
|
||||
<a href="http://www.research.att.com/~bs/3rd_loc0.html">pointer</a>
|
||||
to Appendix D of his book,
|
||||
<a href="http://www.research.att.com/~bs/3rd.html">The C++
|
||||
Programming Language (3rd Edition)</a>. It is a detailed
|
||||
description of locales and how to use them.
|
||||
</p>
|
||||
<p>He also writes:
|
||||
</p>
|
||||
<blockquote><em>
|
||||
Please note that I still consider this detailed description of
|
||||
locales beyond the needs of most C++ programmers. It is written
|
||||
with experienced programmers in mind and novices will do best to
|
||||
avoid it.
|
||||
</em></blockquote>
|
||||
|
||||
<hr />
|
||||
<h2><a name="6">Nathan Myers on Locales</a></h2>
|
||||
<p>An article entitled "The Standard C++ Locale" was
|
||||
published in Dr. Dobb's Journal and can be found
|
||||
<a href="http://www.cantrip.org/locale.html">here</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="7">Correct Transformations</a></h2>
|
||||
<!-- Jumping directly to here from chapter 21. -->
|
||||
<p>A very common question on newsgroups and mailing lists is, "How
|
||||
do I do <foo> to a character string?" where <foo> is
|
||||
a task such as changing all the letters to uppercase, to lowercase,
|
||||
testing for digits, etc. A skilled and conscientious programmer
|
||||
will follow the question with another, "And how do I make the
|
||||
code portable?"
|
||||
</p>
|
||||
<p>(Poor innocent programmer, you have no idea the depths of trouble
|
||||
you are getting yourself into. 'Twould be best for your sanity if
|
||||
you dropped the whole idea and took up basket weaving instead. No?
|
||||
Fine, you asked for it...)
|
||||
</p>
|
||||
<p>The task of changing the case of a letter or classifying a character
|
||||
as numeric, graphical, etc., all depends on the cultural context of the
|
||||
program at runtime. So, first you must take the portability question
|
||||
into account. Once you have localized the program to a particular
|
||||
natural language, only then can you perform the specific task.
|
||||
Unfortunately, specializing a function for a human language is not
|
||||
as simple as declaring
|
||||
<code> extern "Danish" int tolower (int); </code>.
|
||||
</p>
|
||||
<p>The C++ code to do all this proceeds in the same way. First, a locale
|
||||
is created. Then member functions of that locale are called to
|
||||
perform minor tasks. Continuing the example from Chapter 21, we wish
|
||||
to use the following convenience functions:
|
||||
</p>
|
||||
<pre>
|
||||
namespace std {
|
||||
template <class charT>
|
||||
charT
|
||||
toupper (charT c, const locale& loc) const;
|
||||
template <class charT>
|
||||
charT
|
||||
tolower (charT c, const locale& loc) const;
|
||||
}</pre>
|
||||
<p>
|
||||
This function extracts the appropriate "facet" from the
|
||||
locale <em>loc</em> and calls the appropriate member function of that
|
||||
facet, passing <em>c</em> as its argument. The resulting character
|
||||
is returned.
|
||||
</p>
|
||||
<p>For the C/POSIX locale, the results are the same as calling the
|
||||
classic C <code>toupper/tolower</code> function that was used in previous
|
||||
examples. For other locales, the code should Do The Right Thing.
|
||||
</p>
|
||||
<p>Of course, these functions take a second argument, and the
|
||||
transformation algorithm's operator argument can only take a single
|
||||
parameter. So we write simple wrapper structs to handle that.
|
||||
</p>
|
||||
<p>The next-to-final version of the code started in Chapter 21 looks like:
|
||||
</p>
|
||||
<pre>
|
||||
#include <iterator> // for back_inserter
|
||||
#include <locale>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <cctype> // old <ctype.h>
|
||||
|
||||
struct ToUpper
|
||||
{
|
||||
ToUpper(std::locale const& l) : loc(l) {;}
|
||||
char operator() (char c) const { return std::toupper(c,loc); }
|
||||
private:
|
||||
std::locale const& loc;
|
||||
};
|
||||
|
||||
struct ToLower
|
||||
{
|
||||
ToLower(std::locale const& l) : loc(l) {;}
|
||||
char operator() (char c) const { return std::tolower(c,loc); }
|
||||
private:
|
||||
std::locale const& loc;
|
||||
};
|
||||
|
||||
int main ()
|
||||
{
|
||||
std::string s("Some Kind Of Initial Input Goes Here");
|
||||
ToUpper up(std::locale::classic());
|
||||
ToLower down(std::locale::classic());
|
||||
|
||||
// Change everything into upper case.
|
||||
std::transform(s.begin(), s.end(), s.begin(), up);
|
||||
|
||||
// Change everything into lower case.
|
||||
std::transform(s.begin(), s.end(), s.begin(), down);
|
||||
|
||||
// Change everything back into upper case, but store the
|
||||
// result in a different string.
|
||||
std::string capital_s;
|
||||
std::transform(s.begin(), s.end(), std::back_inserter(capital_s), up);
|
||||
}</pre>
|
||||
<p>The <code>ToUpper</code> and <code>ToLower</code> structs can be
|
||||
generalized for other character types by making <code>operator()</code>
|
||||
a member function template.
|
||||
</p>
|
||||
<p>The final version of the code uses <code>bind2nd</code> to eliminate
|
||||
the wrapper structs, but the resulting code is tricky. I have not
|
||||
shown it here because no compilers currently available to me will
|
||||
handle it.
|
||||
</p>
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<hr />
|
||||
<p class="fineprint"><em>
|
||||
See <a href="../17_intro/license.html">license.html</a> for copying conditions.
|
||||
Comments and suggestions are welcome, and may be sent to
|
||||
<a href="mailto:libstdc++@gcc.gnu.org">the libstdc++ mailing list</a>.
|
||||
</em></p>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,543 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta name="AUTHOR" content="bkoz@redhat.com (Benjamin Kosnik)" />
|
||||
<meta name="KEYWORDS" content="HOWTO, libstdc++, locale name LC_ALL" />
|
||||
<meta name="DESCRIPTION" content="Notes on the locale implementation." />
|
||||
<title>Notes on the locale implementation.</title>
|
||||
<link rel="StyleSheet" href="../lib3styles.css" type="text/css" />
|
||||
<link rel="Start" href="../documentation.html" type="text/html"
|
||||
title="GNU C++ Standard Library" />
|
||||
<link rel="Bookmark" href="howto.html" type="text/html" title="Localization" />
|
||||
<link rel="Copyright" href="../17_intro/license.html" type="text/html" />
|
||||
<link rel="Help" href="../faq/index.html" type="text/html" title="F.A.Q." />
|
||||
</head>
|
||||
<body>
|
||||
<h1>
|
||||
Notes on the locale implementation.
|
||||
</h1>
|
||||
<em>
|
||||
prepared by Benjamin Kosnik (bkoz@redhat.com) on October 14, 2002
|
||||
</em>
|
||||
|
||||
<h2>
|
||||
1. Abstract
|
||||
</h2>
|
||||
<p>
|
||||
Describes the basic locale object, including nested
|
||||
classes id, facet, and the reference-counted implementation object,
|
||||
class _Impl.
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
2. What the standard says
|
||||
</h2>
|
||||
Class locale is non-templatized and has two distinct types nested
|
||||
inside of it:
|
||||
|
||||
<blockquote>
|
||||
<em>
|
||||
class facet
|
||||
22.1.1.1.2 Class locale::facet
|
||||
</em>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
Facets actually implement locale functionality. For instance, a facet
|
||||
called numpunct is the data objects that can be used to query for the
|
||||
thousands separator is in the German locale.
|
||||
</p>
|
||||
|
||||
Literally, a facet is strictly defined:
|
||||
<ul>
|
||||
<li>containing the following public data member:
|
||||
<p>
|
||||
<code>static locale::id id;</code>
|
||||
</p>
|
||||
</li>
|
||||
|
||||
<li>derived from another facet:
|
||||
<p>
|
||||
<code> class gnu_codecvt: public std::ctype<user-defined-type></code>
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
Of interest in this class are the memory management options explicitly
|
||||
specified as an argument to facet's constructor. Each constructor of a
|
||||
facet class takes a std::size_t __refs argument: if __refs == 0, the
|
||||
facet is deleted when the locale containing it is destroyed. If __refs
|
||||
== 1, the facet is not destroyed, even when it is no longer
|
||||
referenced.
|
||||
</p>
|
||||
|
||||
<blockquote>
|
||||
<em>
|
||||
class id
|
||||
22.1.1.1.3 - Class locale::id
|
||||
</em>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
Provides an index for looking up specific facets.
|
||||
</p>
|
||||
|
||||
|
||||
<h2>
|
||||
3. Interacting with "C" locales.
|
||||
</h2>
|
||||
|
||||
<p>
|
||||
Some help on determining the underlying support for locales on a system.
|
||||
Note, this is specific to linux (and glibc-2.3.x)
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li> <code>`locale -a`</code> displays available locales.
|
||||
<blockquote>
|
||||
<pre>
|
||||
af_ZA
|
||||
ar_AE
|
||||
ar_AE.utf8
|
||||
ar_BH
|
||||
ar_BH.utf8
|
||||
ar_DZ
|
||||
ar_DZ.utf8
|
||||
ar_EG
|
||||
ar_EG.utf8
|
||||
ar_IN
|
||||
ar_IQ
|
||||
ar_IQ.utf8
|
||||
ar_JO
|
||||
ar_JO.utf8
|
||||
ar_KW
|
||||
ar_KW.utf8
|
||||
ar_LB
|
||||
ar_LB.utf8
|
||||
ar_LY
|
||||
ar_LY.utf8
|
||||
ar_MA
|
||||
ar_MA.utf8
|
||||
ar_OM
|
||||
ar_OM.utf8
|
||||
ar_QA
|
||||
ar_QA.utf8
|
||||
ar_SA
|
||||
ar_SA.utf8
|
||||
ar_SD
|
||||
ar_SD.utf8
|
||||
ar_SY
|
||||
ar_SY.utf8
|
||||
ar_TN
|
||||
ar_TN.utf8
|
||||
ar_YE
|
||||
ar_YE.utf8
|
||||
be_BY
|
||||
be_BY.utf8
|
||||
bg_BG
|
||||
bg_BG.utf8
|
||||
br_FR
|
||||
bs_BA
|
||||
C
|
||||
ca_ES
|
||||
ca_ES@euro
|
||||
ca_ES.utf8
|
||||
ca_ES.utf8@euro
|
||||
cs_CZ
|
||||
cs_CZ.utf8
|
||||
cy_GB
|
||||
da_DK
|
||||
da_DK.iso885915
|
||||
da_DK.utf8
|
||||
de_AT
|
||||
de_AT@euro
|
||||
de_AT.utf8
|
||||
de_AT.utf8@euro
|
||||
de_BE
|
||||
de_BE@euro
|
||||
de_BE.utf8
|
||||
de_BE.utf8@euro
|
||||
de_CH
|
||||
de_CH.utf8
|
||||
de_DE
|
||||
de_DE@euro
|
||||
de_DE.utf8
|
||||
de_DE.utf8@euro
|
||||
de_LU
|
||||
de_LU@euro
|
||||
de_LU.utf8
|
||||
de_LU.utf8@euro
|
||||
el_GR
|
||||
el_GR.utf8
|
||||
en_AU
|
||||
en_AU.utf8
|
||||
en_BW
|
||||
en_BW.utf8
|
||||
en_CA
|
||||
en_CA.utf8
|
||||
en_DK
|
||||
en_DK.utf8
|
||||
en_GB
|
||||
en_GB.iso885915
|
||||
en_GB.utf8
|
||||
en_HK
|
||||
en_HK.utf8
|
||||
en_IE
|
||||
en_IE@euro
|
||||
en_IE.utf8
|
||||
en_IE.utf8@euro
|
||||
en_IN
|
||||
en_NZ
|
||||
en_NZ.utf8
|
||||
en_PH
|
||||
en_PH.utf8
|
||||
en_SG
|
||||
en_SG.utf8
|
||||
en_US
|
||||
en_US.iso885915
|
||||
en_US.utf8
|
||||
en_ZA
|
||||
en_ZA.utf8
|
||||
en_ZW
|
||||
en_ZW.utf8
|
||||
es_AR
|
||||
es_AR.utf8
|
||||
es_BO
|
||||
es_BO.utf8
|
||||
es_CL
|
||||
es_CL.utf8
|
||||
es_CO
|
||||
es_CO.utf8
|
||||
es_CR
|
||||
es_CR.utf8
|
||||
es_DO
|
||||
es_DO.utf8
|
||||
es_EC
|
||||
es_EC.utf8
|
||||
es_ES
|
||||
es_ES@euro
|
||||
es_ES.utf8
|
||||
es_ES.utf8@euro
|
||||
es_GT
|
||||
es_GT.utf8
|
||||
es_HN
|
||||
es_HN.utf8
|
||||
es_MX
|
||||
es_MX.utf8
|
||||
es_NI
|
||||
es_NI.utf8
|
||||
es_PA
|
||||
es_PA.utf8
|
||||
es_PE
|
||||
es_PE.utf8
|
||||
es_PR
|
||||
es_PR.utf8
|
||||
es_PY
|
||||
es_PY.utf8
|
||||
es_SV
|
||||
es_SV.utf8
|
||||
es_US
|
||||
es_US.utf8
|
||||
es_UY
|
||||
es_UY.utf8
|
||||
es_VE
|
||||
es_VE.utf8
|
||||
et_EE
|
||||
et_EE.utf8
|
||||
eu_ES
|
||||
eu_ES@euro
|
||||
eu_ES.utf8
|
||||
eu_ES.utf8@euro
|
||||
fa_IR
|
||||
fi_FI
|
||||
fi_FI@euro
|
||||
fi_FI.utf8
|
||||
fi_FI.utf8@euro
|
||||
fo_FO
|
||||
fo_FO.utf8
|
||||
fr_BE
|
||||
fr_BE@euro
|
||||
fr_BE.utf8
|
||||
fr_BE.utf8@euro
|
||||
fr_CA
|
||||
fr_CA.utf8
|
||||
fr_CH
|
||||
fr_CH.utf8
|
||||
fr_FR
|
||||
fr_FR@euro
|
||||
fr_FR.utf8
|
||||
fr_FR.utf8@euro
|
||||
fr_LU
|
||||
fr_LU@euro
|
||||
fr_LU.utf8
|
||||
fr_LU.utf8@euro
|
||||
ga_IE
|
||||
ga_IE@euro
|
||||
ga_IE.utf8
|
||||
ga_IE.utf8@euro
|
||||
gl_ES
|
||||
gl_ES@euro
|
||||
gl_ES.utf8
|
||||
gl_ES.utf8@euro
|
||||
gv_GB
|
||||
gv_GB.utf8
|
||||
he_IL
|
||||
he_IL.utf8
|
||||
hi_IN
|
||||
hr_HR
|
||||
hr_HR.utf8
|
||||
hu_HU
|
||||
hu_HU.utf8
|
||||
id_ID
|
||||
id_ID.utf8
|
||||
is_IS
|
||||
is_IS.utf8
|
||||
it_CH
|
||||
it_CH.utf8
|
||||
it_IT
|
||||
it_IT@euro
|
||||
it_IT.utf8
|
||||
it_IT.utf8@euro
|
||||
iw_IL
|
||||
iw_IL.utf8
|
||||
ja_JP.eucjp
|
||||
ja_JP.utf8
|
||||
ka_GE
|
||||
kl_GL
|
||||
kl_GL.utf8
|
||||
ko_KR.euckr
|
||||
ko_KR.utf8
|
||||
kw_GB
|
||||
kw_GB.utf8
|
||||
lt_LT
|
||||
lt_LT.utf8
|
||||
lv_LV
|
||||
lv_LV.utf8
|
||||
mi_NZ
|
||||
mk_MK
|
||||
mk_MK.utf8
|
||||
mr_IN
|
||||
ms_MY
|
||||
ms_MY.utf8
|
||||
mt_MT
|
||||
mt_MT.utf8
|
||||
nl_BE
|
||||
nl_BE@euro
|
||||
nl_BE.utf8
|
||||
nl_BE.utf8@euro
|
||||
nl_NL
|
||||
nl_NL@euro
|
||||
nl_NL.utf8
|
||||
nl_NL.utf8@euro
|
||||
nn_NO
|
||||
nn_NO.utf8
|
||||
no_NO
|
||||
no_NO.utf8
|
||||
oc_FR
|
||||
pl_PL
|
||||
pl_PL.utf8
|
||||
POSIX
|
||||
pt_BR
|
||||
pt_BR.utf8
|
||||
pt_PT
|
||||
pt_PT@euro
|
||||
pt_PT.utf8
|
||||
pt_PT.utf8@euro
|
||||
ro_RO
|
||||
ro_RO.utf8
|
||||
ru_RU
|
||||
ru_RU.koi8r
|
||||
ru_RU.utf8
|
||||
ru_UA
|
||||
ru_UA.utf8
|
||||
se_NO
|
||||
sk_SK
|
||||
sk_SK.utf8
|
||||
sl_SI
|
||||
sl_SI.utf8
|
||||
sq_AL
|
||||
sq_AL.utf8
|
||||
sr_YU
|
||||
sr_YU@cyrillic
|
||||
sr_YU.utf8
|
||||
sr_YU.utf8@cyrillic
|
||||
sv_FI
|
||||
sv_FI@euro
|
||||
sv_FI.utf8
|
||||
sv_FI.utf8@euro
|
||||
sv_SE
|
||||
sv_SE.iso885915
|
||||
sv_SE.utf8
|
||||
ta_IN
|
||||
te_IN
|
||||
tg_TJ
|
||||
th_TH
|
||||
th_TH.utf8
|
||||
tl_PH
|
||||
tr_TR
|
||||
tr_TR.utf8
|
||||
uk_UA
|
||||
uk_UA.utf8
|
||||
ur_PK
|
||||
uz_UZ
|
||||
vi_VN
|
||||
vi_VN.tcvn
|
||||
wa_BE
|
||||
wa_BE@euro
|
||||
yi_US
|
||||
zh_CN
|
||||
zh_CN.gb18030
|
||||
zh_CN.gbk
|
||||
zh_CN.utf8
|
||||
zh_HK
|
||||
zh_HK.utf8
|
||||
zh_TW
|
||||
zh_TW.euctw
|
||||
zh_TW.utf8
|
||||
</pre>
|
||||
</blockquote>
|
||||
</li>
|
||||
|
||||
<li> <code>`locale`</code> displays environmental variables
|
||||
that impact how locale("") will be deduced.
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
LANG=en_US
|
||||
LC_CTYPE="en_US"
|
||||
LC_NUMERIC="en_US"
|
||||
LC_TIME="en_US"
|
||||
LC_COLLATE="en_US"
|
||||
LC_MONETARY="en_US"
|
||||
LC_MESSAGES="en_US"
|
||||
LC_PAPER="en_US"
|
||||
LC_NAME="en_US"
|
||||
LC_ADDRESS="en_US"
|
||||
LC_TELEPHONE="en_US"
|
||||
LC_MEASUREMENT="en_US"
|
||||
LC_IDENTIFICATION="en_US"
|
||||
LC_ALL=
|
||||
</pre>
|
||||
</blockquote>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
From Josuttis, p. 697-698, which says, that "there is only *one*
|
||||
relation (of the C++ locale mechanism) to the C locale mechanism: the
|
||||
global C locale is modified if a named C++ locale object is set as the
|
||||
global locale" (emphasis Paolo), that is:
|
||||
</p>
|
||||
<code>std::locale::global(std::locale(""));</code>
|
||||
|
||||
<p>affects the C functions as if the following call was made:</p>
|
||||
|
||||
<code>std::setlocale(LC_ALL, "");</code>
|
||||
|
||||
<p>
|
||||
On the other hand, there is *no* viceversa, that is, calling setlocale
|
||||
has *no* whatsoever on the C++ locale mechanism, in particular on the
|
||||
working of locale(""), which constructs the locale object from the
|
||||
environment of the running program, that is, in practice, the set of
|
||||
LC_ALL, LANG, etc. variable of the shell.
|
||||
</p>
|
||||
|
||||
|
||||
<h2>
|
||||
4. Design
|
||||
</h2>
|
||||
|
||||
|
||||
<p>
|
||||
The major design challenge is fitting an object-orientated and
|
||||
non-global locale design ontop of POSIX and other relevant stanards,
|
||||
which include the Single Unix (nee X/Open.)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Because POSIX falls down so completely, portibility is an issue.
|
||||
</p>
|
||||
|
||||
class _Impl
|
||||
The internal representation of the std::locale object.
|
||||
|
||||
|
||||
<h2>
|
||||
5. Examples
|
||||
</h2>
|
||||
|
||||
More information can be found in the following testcases:
|
||||
<ul>
|
||||
<li> testsuite/22_locale/all </li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
6. Unresolved Issues
|
||||
</h2>
|
||||
|
||||
<ul>
|
||||
<li> locale initialization: at what point does _S_classic,
|
||||
_S_global get initialized? Can named locales assume this
|
||||
initialization has already taken place? </li>
|
||||
|
||||
<li> document how named locales error check when filling data
|
||||
members. Ie, a fr_FR locale that doesn't have
|
||||
numpunct::truename(): does it use "true"? Or is it a blank
|
||||
string? What's the convention? </li>
|
||||
|
||||
<li> explain how locale aliasing happens. When does "de_DE"
|
||||
use "de" information? What is the rule for locales composed of
|
||||
just an ISO language code (say, "de") and locales with both an
|
||||
ISO language code and ISO country code (say, "de_DE"). </li>
|
||||
|
||||
<li> what should non-required facet instantiations do? If the
|
||||
generic implemenation is provided, then how to end-users
|
||||
provide specializations? </li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
7. Acknowledgments
|
||||
</h2>
|
||||
|
||||
<h2>
|
||||
8. Bibliography / Referenced Documents
|
||||
</h2>
|
||||
|
||||
Drepper, Ulrich, GNU libc (glibc) 2.2 manual. In particular, Chapters "6. Character Set Handling" and "7 Locales and Internationalization"
|
||||
|
||||
<p>
|
||||
Drepper, Ulrich, Numerous, late-night email correspondence
|
||||
</p>
|
||||
|
||||
<p>
|
||||
ISO/IEC 14882:1998 Programming languages - C++
|
||||
</p>
|
||||
|
||||
<p>
|
||||
ISO/IEC 9899:1999 Programming languages - C
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Langer, Angelika and Klaus Kreft, Standard C++ IOStreams and Locales, Advanced Programmer's Guide and Reference, Addison Wesley Longman, Inc. 2000
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Stroustrup, Bjarne, Appendix D, The C++ Programming Language, Special Edition, Addison Wesley, Inc. 2000
|
||||
</p>
|
||||
|
||||
<p>
|
||||
System Interface Definitions, Issue 6 (IEEE Std. 1003.1-200x)
|
||||
The Open Group/The Institute of Electrical and Electronics Engineers, Inc.
|
||||
http://www.opennc.org/austin/docreg.html
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
@ -1,461 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta name="AUTHOR" content="bkoz@redhat.com (Benjamin Kosnik)" />
|
||||
<meta name="KEYWORDS" content="HOWTO, libstdc++, GCC, g++, libg++, STL" />
|
||||
<meta name="DESCRIPTION" content="Notes on the messages implementation." />
|
||||
<title>Notes on the messages implementation.</title>
|
||||
<link rel="StyleSheet" href="../lib3styles.css" type="text/css" />
|
||||
<link rel="Start" href="../documentation.html" type="text/html"
|
||||
title="GNU C++ Standard Library" />
|
||||
<link rel="Bookmark" href="howto.html" type="text/html" title="Localization" />
|
||||
<link rel="Copyright" href="../17_intro/license.html" type="text/html" />
|
||||
<link rel="Help" href="../faq/index.html" type="text/html" title="F.A.Q." />
|
||||
</head>
|
||||
<body>
|
||||
<h1>
|
||||
Notes on the messages implementation.
|
||||
</h1>
|
||||
<em>
|
||||
prepared by Benjamin Kosnik (bkoz@redhat.com) on August 8, 2001
|
||||
</em>
|
||||
|
||||
<h2>
|
||||
1. Abstract
|
||||
</h2>
|
||||
<p>
|
||||
The std::messages facet implements message retrieval functionality
|
||||
equivalent to Java's java.text.MessageFormat .using either GNU gettext
|
||||
or IEEE 1003.1-200 functions.
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
2. What the standard says
|
||||
</h2>
|
||||
The std::messages facet is probably the most vaguely defined facet in
|
||||
the standard library. It's assumed that this facility was built into
|
||||
the standard library in order to convert string literals from one
|
||||
locale to the other. For instance, converting the "C" locale's
|
||||
<code>const char* c = "please"</code> to a German-localized <code>"bitte"</code>
|
||||
during program execution.
|
||||
|
||||
<blockquote>
|
||||
22.2.7.1 - Template class messages [lib.locale.messages]
|
||||
</blockquote>
|
||||
|
||||
This class has three public member functions, which directly
|
||||
correspond to three protected virtual member functions.
|
||||
|
||||
The public member functions are:
|
||||
|
||||
<p>
|
||||
<code>catalog open(const string&, const locale&) const</code>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<code>string_type get(catalog, int, int, const string_type&) const</code>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<code>void close(catalog) const</code>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
While the virtual functions are:
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<code>catalog do_open(const string&, const locale&) const</code>
|
||||
</p>
|
||||
<blockquote>
|
||||
<em>
|
||||
-1- Returns: A value that may be passed to get() to retrieve a
|
||||
message, from the message catalog identified by the string name
|
||||
according to an implementation-defined mapping. The result can be used
|
||||
until it is passed to close(). Returns a value less than 0 if no such
|
||||
catalog can be opened.
|
||||
</em>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
<code>string_type do_get(catalog, int, int, const string_type&) const</code>
|
||||
</p>
|
||||
<blockquote>
|
||||
<em>
|
||||
-3- Requires: A catalog cat obtained from open() and not yet closed.
|
||||
-4- Returns: A message identified by arguments set, msgid, and dfault,
|
||||
according to an implementation-defined mapping. If no such message can
|
||||
be found, returns dfault.
|
||||
</em>
|
||||
</blockquote>
|
||||
|
||||
<p>
|
||||
<code>void do_close(catalog) const</code>
|
||||
</p>
|
||||
<blockquote>
|
||||
<em>
|
||||
-5- Requires: A catalog cat obtained from open() and not yet closed.
|
||||
-6- Effects: Releases unspecified resources associated with cat.
|
||||
-7- Notes: The limit on such resources, if any, is implementation-defined.
|
||||
</em>
|
||||
</blockquote>
|
||||
|
||||
|
||||
<h2>
|
||||
3. Problems with "C" messages: thread safety,
|
||||
over-specification, and assumptions.
|
||||
</h2>
|
||||
A couple of notes on the standard.
|
||||
|
||||
<p>
|
||||
First, why is <code>messages_base::catalog</code> specified as a typedef
|
||||
to int? This makes sense for implementations that use
|
||||
<code>catopen</code>, but not for others. Fortunately, it's not heavily
|
||||
used and so only a minor irritant.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Second, by making the member functions <code>const</code>, it is
|
||||
impossible to save state in them. Thus, storing away information used
|
||||
in the 'open' member function for use in 'get' is impossible. This is
|
||||
unfortunate.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The 'open' member function in particular seems to be oddly
|
||||
designed. The signature seems quite peculiar. Why specify a <code>const
|
||||
string& </code> argument, for instance, instead of just <code>const
|
||||
char*</code>? Or, why specify a <code>const locale&</code> argument that is
|
||||
to be used in the 'get' member function? How, exactly, is this locale
|
||||
argument useful? What was the intent? It might make sense if a locale
|
||||
argument was associated with a given default message string in the
|
||||
'open' member function, for instance. Quite murky and unclear, on
|
||||
reflection.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Lastly, it seems odd that messages, which explicitly require code
|
||||
conversion, don't use the codecvt facet. Because the messages facet
|
||||
has only one template parameter, it is assumed that ctype, and not
|
||||
codecvt, is to be used to convert between character sets.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
It is implicitly assumed that the locale for the default message
|
||||
string in 'get' is in the "C" locale. Thus, all source code is assumed
|
||||
to be written in English, so translations are always from "en_US" to
|
||||
other, explicitly named locales.
|
||||
</p>
|
||||
|
||||
<h2>
|
||||
4. Design and Implementation Details
|
||||
</h2>
|
||||
This is a relatively simple class, on the face of it. The standard
|
||||
specifies very little in concrete terms, so generic implementations
|
||||
that are conforming yet do very little are the norm. Adding
|
||||
functionality that would be useful to programmers and comparable to
|
||||
Java's java.text.MessageFormat takes a bit of work, and is highly
|
||||
dependent on the capabilities of the underlying operating system.
|
||||
|
||||
<p>
|
||||
Three different mechanisms have been provided, selectable via
|
||||
configure flags:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li> generic
|
||||
<p>
|
||||
This model does very little, and is what is used by default.
|
||||
</p>
|
||||
</li>
|
||||
|
||||
<li> gnu
|
||||
<p>
|
||||
The gnu model is complete and fully tested. It's based on the
|
||||
GNU gettext package, which is part of glibc. It uses the functions
|
||||
<code>textdomain, bindtextdomain, gettext</code>
|
||||
to implement full functionality. Creating message
|
||||
catalogs is a relatively straight-forward process and is
|
||||
lightly documented below, and fully documented in gettext's
|
||||
distributed documentation.
|
||||
</p>
|
||||
</li>
|
||||
|
||||
<li> ieee_1003.1-200x
|
||||
<p>
|
||||
This is a complete, though untested, implementation based on
|
||||
the IEEE standard. The functions
|
||||
<code>catopen, catgets, catclose</code>
|
||||
are used to retrieve locale-specific messages given the
|
||||
appropriate message catalogs that have been constructed for
|
||||
their use. Note, the script <code> po2msg.sed</code> that is part
|
||||
of the gettext distribution can convert gettext catalogs into
|
||||
catalogs that <code>catopen</code> can use.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
A new, standards-conformant non-virtual member function signature was
|
||||
added for 'open' so that a directory could be specified with a given
|
||||
message catalog. This simplifies calling conventions for the gnu
|
||||
model.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The rest of this document discusses details of the GNU model.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The messages facet, because it is retrieving and converting between
|
||||
characters sets, depends on the ctype and perhaps the codecvt facet in
|
||||
a given locale. In addition, underlying "C" library locale support is
|
||||
necessary for more than just the <code>LC_MESSAGES</code> mask:
|
||||
<code>LC_CTYPE</code> is also necessary. To avoid any unpleasantness, all
|
||||
bits of the "C" mask (ie <code>LC_ALL</code>) are set before retrieving
|
||||
messages.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Making the message catalogs can be initially tricky, but become quite
|
||||
simple with practice. For complete info, see the gettext
|
||||
documentation. Here's an idea of what is required:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li> Make a source file with the required string literals
|
||||
that need to be translated. See
|
||||
<code>intl/string_literals.cc</code> for an example.
|
||||
</li>
|
||||
|
||||
<li> Make initial catalog (see "4 Making the PO Template File"
|
||||
from the gettext docs).
|
||||
<p>
|
||||
<code> xgettext --c++ --debug string_literals.cc -o libstdc++.pot </code>
|
||||
</p>
|
||||
</li>
|
||||
|
||||
<li> Make language and country-specific locale catalogs.
|
||||
<p>
|
||||
<code>cp libstdc++.pot fr_FR.po</code>
|
||||
</p>
|
||||
<p>
|
||||
<code>cp libstdc++.pot de_DE.po</code>
|
||||
</p>
|
||||
</li>
|
||||
|
||||
<li> Edit localized catalogs in emacs so that strings are
|
||||
translated.
|
||||
<p>
|
||||
<code>emacs fr_FR.po</code>
|
||||
</p>
|
||||
</li>
|
||||
|
||||
<li> Make the binary mo files.
|
||||
<p>
|
||||
<code>msgfmt fr_FR.po -o fr_FR.mo</code>
|
||||
</p>
|
||||
<p>
|
||||
<code>msgfmt de_DE.po -o de_DE.mo</code>
|
||||
</p>
|
||||
</li>
|
||||
|
||||
<li> Copy the binary files into the correct directory structure.
|
||||
<p>
|
||||
<code>cp fr_FR.mo (dir)/fr_FR/LC_MESSAGES/libstdc++.mo</code>
|
||||
</p>
|
||||
<p>
|
||||
<code>cp de_DE.mo (dir)/de_DE/LC_MESSAGES/libstdc++.mo</code>
|
||||
</p>
|
||||
</li>
|
||||
|
||||
<li> Use the new message catalogs.
|
||||
<p>
|
||||
<code>locale loc_de("de_DE");</code>
|
||||
</p>
|
||||
<p>
|
||||
<code>
|
||||
use_facet<messages<char> >(loc_de).open("libstdc++", locale(), dir);
|
||||
</code>
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
5. Examples
|
||||
</h2>
|
||||
|
||||
<ul>
|
||||
<li> message converting, simple example using the GNU model.
|
||||
|
||||
<pre>
|
||||
#include <iostream>
|
||||
#include <locale>
|
||||
using namespace std;
|
||||
|
||||
void test01()
|
||||
{
|
||||
typedef messages<char>::catalog catalog;
|
||||
const char* dir =
|
||||
"/mnt/egcs/build/i686-pc-linux-gnu/libstdc++/po/share/locale";
|
||||
const locale loc_de("de_DE");
|
||||
const messages<char>& mssg_de = use_facet<messages<char> >(loc_de);
|
||||
|
||||
catalog cat_de = mssg_de.open("libstdc++", loc_de, dir);
|
||||
string s01 = mssg_de.get(cat_de, 0, 0, "please");
|
||||
string s02 = mssg_de.get(cat_de, 0, 0, "thank you");
|
||||
cout << "please in german:" << s01 << '\n';
|
||||
cout << "thank you in german:" << s02 << '\n';
|
||||
mssg_de.close(cat_de);
|
||||
}
|
||||
</pre>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
More information can be found in the following testcases:
|
||||
<ul>
|
||||
<li> testsuite/22_locale/messages.cc </li>
|
||||
<li> testsuite/22_locale/messages_byname.cc </li>
|
||||
<li> testsuite/22_locale/messages_char_members.cc </li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
6. Unresolved Issues
|
||||
</h2>
|
||||
<ul>
|
||||
<li> Things that are sketchy, or remain unimplemented:
|
||||
<ul>
|
||||
<li>_M_convert_from_char, _M_convert_to_char are in
|
||||
flux, depending on how the library ends up doing
|
||||
character set conversions. It might not be possible to
|
||||
do a real character set based conversion, due to the
|
||||
fact that the template parameter for messages is not
|
||||
enough to instantiate the codecvt facet (1 supplied,
|
||||
need at least 2 but would prefer 3).
|
||||
</li>
|
||||
|
||||
<li> There are issues with gettext needing the global
|
||||
locale set to extract a message. This dependence on
|
||||
the global locale makes the current "gnu" model non
|
||||
MT-safe. Future versions of glibc, ie glibc 2.3.x will
|
||||
fix this, and the C++ library bits are already in
|
||||
place.
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li> Development versions of the GNU "C" library, glibc 2.3 will allow
|
||||
a more efficient, MT implementation of std::messages, and will
|
||||
allow the removal of the _M_name_messages data member. If this
|
||||
is done, it will change the library ABI. The C++ parts to
|
||||
support glibc 2.3 have already been coded, but are not in use:
|
||||
once this version of the "C" library is released, the marked
|
||||
parts of the messages implementation can be switched over to
|
||||
the new "C" library functionality.
|
||||
</li>
|
||||
<li> At some point in the near future, std::numpunct will probably use
|
||||
std::messages facilities to implement truename/falename
|
||||
correctly. This is currently not done, but entries in
|
||||
libstdc++.pot have already been made for "true" and "false"
|
||||
string literals, so all that remains is the std::numpunct
|
||||
coding and the configure/make hassles to make the installed
|
||||
library search its own catalog. Currently the libstdc++.mo
|
||||
catalog is only searched for the testsuite cases involving
|
||||
messages members.
|
||||
</li>
|
||||
|
||||
<li> The following member functions:
|
||||
|
||||
<p>
|
||||
<code>
|
||||
catalog
|
||||
open(const basic_string<char>& __s, const locale& __loc) const
|
||||
</code>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<code>
|
||||
catalog
|
||||
open(const basic_string<char>&, const locale&, const char*) const;
|
||||
</code>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Don't actually return a "value less than 0 if no such catalog
|
||||
can be opened" as required by the standard in the "gnu"
|
||||
model. As of this writing, it is unknown how to query to see
|
||||
if a specified message catalog exists using the gettext
|
||||
package.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2>
|
||||
7. Acknowledgments
|
||||
</h2>
|
||||
Ulrich Drepper for the character set explanations, gettext details,
|
||||
and patient answering of late-night questions, Tom Tromey for the java details.
|
||||
|
||||
|
||||
<h2>
|
||||
8. Bibliography / Referenced Documents
|
||||
</h2>
|
||||
|
||||
Drepper, Ulrich, GNU libc (glibc) 2.2 manual. In particular, Chapters
|
||||
"7 Locales and Internationalization"
|
||||
|
||||
<p>
|
||||
Drepper, Ulrich, Thread-Aware Locale Model, A proposal. This is a
|
||||
draft document describing the design of glibc 2.3 MT locale
|
||||
functionality.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Drepper, Ulrich, Numerous, late-night email correspondence
|
||||
</p>
|
||||
|
||||
<p>
|
||||
ISO/IEC 9899:1999 Programming languages - C
|
||||
</p>
|
||||
|
||||
<p>
|
||||
ISO/IEC 14882:1998 Programming languages - C++
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Java 2 Platform, Standard Edition, v 1.3.1 API Specification. In
|
||||
particular, java.util.Properties, java.text.MessageFormat,
|
||||
java.util.Locale, java.util.ResourceBundle.
|
||||
http://java.sun.com/j2se/1.3/docs/api
|
||||
</p>
|
||||
|
||||
<p>
|
||||
System Interface Definitions, Issue 7 (IEEE Std. 1003.1-200x)
|
||||
The Open Group/The Institute of Electrical and Electronics Engineers, Inc.
|
||||
In particular see lines 5268-5427.
|
||||
http://www.opennc.org/austin/docreg.html
|
||||
</p>
|
||||
|
||||
<p> GNU gettext tools, version 0.10.38, Native Language Support
|
||||
Library and Tools.
|
||||
http://sources.redhat.com/gettext
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Langer, Angelika and Klaus Kreft, Standard C++ IOStreams and Locales,
|
||||
Advanced Programmer's Guide and Reference, Addison Wesley Longman,
|
||||
Inc. 2000. See page 725, Internationalized Messages.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Stroustrup, Bjarne, Appendix D, The C++ Programming Language, Special Edition, Addison Wesley, Inc. 2000
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,457 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta name="AUTHOR" content="pme@gcc.gnu.org (Phil Edwards)" />
|
||||
<meta name="KEYWORDS" content="HOWTO, libstdc++, GCC, g++, libg++, STL" />
|
||||
<meta name="DESCRIPTION" content="HOWTO for the libstdc++ chapter 23." />
|
||||
<meta name="GENERATOR" content="vi and eight fingers" />
|
||||
<title>libstdc++ HOWTO: Chapter 23: Containers</title>
|
||||
<link rel="StyleSheet" href="../lib3styles.css" type="text/css" />
|
||||
<link rel="Start" href="../documentation.html" type="text/html"
|
||||
title="GNU C++ Standard Library" />
|
||||
<link rel="Prev" href="../22_locale/howto.html" type="text/html"
|
||||
title="Localization" />
|
||||
<link rel="Next" href="../24_iterators/howto.html" type="text/html"
|
||||
title="Iterators" />
|
||||
<link rel="Copyright" href="../17_intro/license.html" type="text/html" />
|
||||
<link rel="Help" href="../faq/index.html" type="text/html" title="F.A.Q." />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 class="centered"><a name="top">Chapter 23: Containers</a></h1>
|
||||
|
||||
<p>Chapter 23 deals with container classes and what they offer.
|
||||
</p>
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
<hr />
|
||||
<h1>Contents</h1>
|
||||
<ul>
|
||||
<li><a href="#1">Making code unaware of the container/array difference</a></li>
|
||||
<li><a href="#2">Variable-sized bitmasks</a></li>
|
||||
<li><a href="#3">Containers and multithreading</a></li>
|
||||
<li><a href="#4">"Hinting" during insertion</a></li>
|
||||
<li><a href="#5">Bitmasks and string arguments</a></li>
|
||||
<li><a href="#6"><code>std::list::size()</code> is O(n)!</a></li>
|
||||
<li><a href="#7">Space overhead management for vectors</a></li>
|
||||
</ul>
|
||||
|
||||
<hr />
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<h2><a name="1">Making code unaware of the container/array difference</a></h2>
|
||||
<p>You're writing some code and can't decide whether to use builtin
|
||||
arrays or some kind of container. There are compelling reasons
|
||||
to use one of the container classes, but you're afraid that you'll
|
||||
eventually run into difficulties, change everything back to arrays,
|
||||
and then have to change all the code that uses those data types to
|
||||
keep up with the change.
|
||||
</p>
|
||||
<p>If your code makes use of the standard algorithms, this isn't as
|
||||
scary as it sounds. The algorithms don't know, nor care, about
|
||||
the kind of "container" on which they work, since the
|
||||
algorithms are only given endpoints to work with. For the container
|
||||
classes, these are iterators (usually <code>begin()</code> and
|
||||
<code>end()</code>, but not always). For builtin arrays, these are
|
||||
the address of the first element and the
|
||||
<a href="../24_iterators/howto.html#2">past-the-end</a> element.
|
||||
</p>
|
||||
<p>Some very simple wrapper functions can hide all of that from the
|
||||
rest of the code. For example, a pair of functions called
|
||||
<code>beginof</code> can be written, one that takes an array, another
|
||||
that takes a vector. The first returns a pointer to the first
|
||||
element, and the second returns the vector's <code>begin()</code>
|
||||
iterator.
|
||||
</p>
|
||||
<p>The functions should be made template functions, and should also
|
||||
be declared inline. As pointed out in the comments in the code
|
||||
below, this can lead to <code>beginof</code> being optimized out of
|
||||
existence, so you pay absolutely nothing in terms of increased
|
||||
code size or execution time.
|
||||
</p>
|
||||
<p>The result is that if all your algorithm calls look like
|
||||
</p>
|
||||
<pre>
|
||||
std::transform(beginof(foo), endof(foo), beginof(foo), SomeFunction);</pre>
|
||||
<p>then the type of foo can change from an array of ints to a vector
|
||||
of ints to a deque of ints and back again, without ever changing any
|
||||
client code.
|
||||
</p>
|
||||
<p>This author has a collection of such functions, called "*of"
|
||||
because they all extend the builtin "sizeof". It started
|
||||
with some Usenet discussions on a transparent way to find the length
|
||||
of an array. A simplified and much-reduced version for easier
|
||||
reading is <a href="wrappers_h.txt">given here</a>.
|
||||
</p>
|
||||
<p>Astute readers will notice two things at once: first, that the
|
||||
container class is still a <code>vector<T></code> instead of a
|
||||
more general <code>Container<T></code>. This would mean that
|
||||
three functions for <code>deque</code> would have to be added, another
|
||||
three for <code>list</code>, and so on. This is due to problems with
|
||||
getting template resolution correct; I find it easier just to
|
||||
give the extra three lines and avoid confusion.
|
||||
</p>
|
||||
<p>Second, the line
|
||||
</p>
|
||||
<pre>
|
||||
inline unsigned int lengthof (T (&)[sz]) { return sz; } </pre>
|
||||
<p>looks just weird! Hint: unused parameters can be left nameless.
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="2">Variable-sized bitmasks</a></h2>
|
||||
<p>No, you cannot write code of the form
|
||||
</p>
|
||||
<!-- Careful, the leading spaces in PRE show up directly. -->
|
||||
<pre>
|
||||
#include <bitset>
|
||||
|
||||
void foo (size_t n)
|
||||
{
|
||||
std::bitset<n> bits;
|
||||
....
|
||||
} </pre>
|
||||
<p>because <code>n</code> must be known at compile time. Your compiler is
|
||||
correct; it is not a bug. That's the way templates work. (Yes, it
|
||||
<em>is</em> a feature.)
|
||||
</p>
|
||||
<p>There are a couple of ways to handle this kind of thing. Please
|
||||
consider all of them before passing judgement. They include, in
|
||||
no particular order:
|
||||
</p>
|
||||
<ul>
|
||||
<li>A very large N in <code>bitset<N></code>.</li>
|
||||
<li>A container<bool>.</li>
|
||||
<li>Extremely weird solutions.</li>
|
||||
</ul>
|
||||
<p><strong>A very large N in
|
||||
<code>bitset<N></code>. </strong> It has
|
||||
been pointed out a few times in newsgroups that N bits only takes up
|
||||
(N/8) bytes on most systems, and division by a factor of eight is pretty
|
||||
impressive when speaking of memory. Half a megabyte given over to a
|
||||
bitset (recall that there is zero space overhead for housekeeping info;
|
||||
it is known at compile time exactly how large the set is) will hold over
|
||||
four million bits. If you're using those bits as status flags (e.g.,
|
||||
"changed"/"unchanged" flags), that's a <em>lot</em>
|
||||
of state.
|
||||
</p>
|
||||
<p>You can then keep track of the "maximum bit used" during some
|
||||
testing runs on representative data, make note of how many of those bits
|
||||
really need to be there, and then reduce N to a smaller number. Leave
|
||||
some extra space, of course. (If you plan to write code like the
|
||||
incorrect example above, where the bitset is a local variable, then you
|
||||
may have to talk your compiler into allowing that much stack space;
|
||||
there may be zero space overhead, but it's all allocated inside the
|
||||
object.)
|
||||
</p>
|
||||
<p><strong>A container<bool>. </strong> The Committee
|
||||
made provision
|
||||
for the space savings possible with that (N/8) usage previously mentioned,
|
||||
so that you don't have to do wasteful things like
|
||||
<code>Container<char></code> or
|
||||
<code>Container<short int></code>.
|
||||
Specifically, <code>vector<bool></code> is required to be
|
||||
specialized for that space savings.
|
||||
</p>
|
||||
<p>The problem is that <code>vector<bool></code> doesn't behave like a
|
||||
normal vector anymore. There have been recent journal articles which
|
||||
discuss the problems (the ones by Herb Sutter in the May and
|
||||
July/August 1999 issues of
|
||||
<u>C++ Report</u> cover it well). Future revisions of the ISO C++
|
||||
Standard will change the requirement for <code>vector<bool></code>
|
||||
specialization. In the meantime, <code>deque<bool></code> is
|
||||
recommended (although its behavior is sane, you probably will not get
|
||||
the space savings, but the allocation scheme is different than that
|
||||
of vector).
|
||||
</p>
|
||||
<p><strong>Extremely weird solutions. </strong> If you have
|
||||
access to
|
||||
the compiler and linker at runtime, you can do something insane, like
|
||||
figuring out just how many bits you need, then writing a temporary
|
||||
source code file. That file contains an instantiation of
|
||||
<code>bitset</code>
|
||||
for the required number of bits, inside some wrapper functions with
|
||||
unchanging signatures. Have your program then call the
|
||||
compiler on that file using Position Independent Code, then open the
|
||||
newly-created object file and load those wrapper functions. You'll have
|
||||
an instantiation of <code>bitset<N></code> for the exact
|
||||
<code>N</code>
|
||||
that you need at the time. Don't forget to delete the temporary files.
|
||||
(Yes, this <em>can</em> be, and <em>has been</em>, done.)
|
||||
</p>
|
||||
<!-- I wonder if this next paragraph will get me in trouble... -->
|
||||
<p>This would be the approach of either a visionary genius or a raving
|
||||
lunatic, depending on your programming and management style. Probably
|
||||
the latter.
|
||||
</p>
|
||||
<p>Which of the above techniques you use, if any, are up to you and your
|
||||
intended application. Some time/space profiling is indicated if it
|
||||
really matters (don't just guess). And, if you manage to do anything
|
||||
along the lines of the third category, the author would love to hear
|
||||
from you...
|
||||
</p>
|
||||
<p>Also note that the implementation of bitset used in libstdc++ has
|
||||
<a href="../ext/sgiexts.html#ch23">some extensions</a>.
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="3">Containers and multithreading</a></h2>
|
||||
<p>This section discusses issues surrounding the design of
|
||||
multithreaded applications which use Standard C++ containers.
|
||||
All information in this section is current as of the gcc 3.0
|
||||
release and all later point releases. Although earlier gcc
|
||||
releases had a different approach to threading configuration and
|
||||
proper compilation, the basic code design rules presented here
|
||||
were similar. For information on all other aspects of
|
||||
multithreading as it relates to libstdc++, including details on
|
||||
the proper compilation of threaded code (and compatibility between
|
||||
threaded and non-threaded code), see Chapter 17.
|
||||
</p>
|
||||
<p>Two excellent pages to read when working with the Standard C++
|
||||
containers and threads are
|
||||
<a href="http://www.sgi.com/tech/stl/thread_safety.html">SGI's
|
||||
http://www.sgi.com/tech/stl/thread_safety.html</a> and
|
||||
<a href="http://www.sgi.com/tech/stl/Allocators.html">SGI's
|
||||
http://www.sgi.com/tech/stl/Allocators.html</a>.
|
||||
</p>
|
||||
<p><em>However, please ignore all discussions about the user-level
|
||||
configuration of the lock implementation inside the STL
|
||||
container-memory allocator on those pages. For the sake of this
|
||||
discussion, libstdc++ configures the SGI STL implementation,
|
||||
not you. This is quite different from how gcc pre-3.0 worked.
|
||||
In particular, past advice was for people using g++ to
|
||||
explicitly define _PTHREADS or other macros or port-specific
|
||||
compilation options on the command line to get a thread-safe
|
||||
STL. This is no longer required for any port and should no
|
||||
longer be done unless you really know what you are doing and
|
||||
assume all responsibility.</em>
|
||||
</p>
|
||||
<p>Since the container implementation of libstdc++ uses the SGI
|
||||
code, we use the same definition of thread safety as SGI when
|
||||
discussing design. A key point that beginners may miss is the
|
||||
fourth major paragraph of the first page mentioned above
|
||||
("For most clients,"...), which points out that
|
||||
locking must nearly always be done outside the container, by
|
||||
client code (that'd be you, not us). There is a notable
|
||||
exceptions to this rule. Allocators called while a container or
|
||||
element is constructed uses an internal lock obtained and
|
||||
released solely within libstdc++ code (in fact, this is the
|
||||
reason STL requires any knowledge of the thread configuration).
|
||||
</p>
|
||||
<p>For implementing a container which does its own locking, it is
|
||||
trivial to provide a wrapper class which obtains the lock (as
|
||||
SGI suggests), performs the container operation, and then
|
||||
releases the lock. This could be templatized <em>to a certain
|
||||
extent</em>, on the underlying container and/or a locking
|
||||
mechanism. Trying to provide a catch-all general template
|
||||
solution would probably be more trouble than it's worth.
|
||||
</p>
|
||||
<p>The STL implementation is currently configured to use the
|
||||
high-speed caching memory allocator. Some people like to
|
||||
test and/or normally run threaded programs with a different
|
||||
default. For all details about how to globally override this
|
||||
at application run-time see <a href="../ext/howto.html#3">here</a>.
|
||||
</p>
|
||||
<p>There is a better way (not standardized yet): It is possible to
|
||||
force the malloc-based allocator on a per-case-basis for some
|
||||
application code. The library team generally believes that this
|
||||
is a better way to tune an application for high-speed using this
|
||||
implementation of the STL. There is
|
||||
<a href="../ext/howto.html#3">more information on allocators here</a>.
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="4">"Hinting" during insertion</a></h2>
|
||||
<p>Section [23.1.2], Table 69, of the C++ standard lists this function
|
||||
for all of the associative containers (map, set, etc):
|
||||
</p>
|
||||
<pre>
|
||||
a.insert(p,t);</pre>
|
||||
<p>where 'p' is an iterator into the container 'a', and 't' is the item
|
||||
to insert. The standard says that "<code>t</code> is inserted
|
||||
as close as possible to the position just prior to
|
||||
<code>p</code>." (Library DR #233 addresses this topic, referring to
|
||||
<a href='http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1780.html'>N1780</a>.
|
||||
Since version 4.2 GCC implements the resolution to DR 233, so that
|
||||
insertions happen as close as possible to the hint. For earlier releases
|
||||
the hint was only used as described below.
|
||||
</p>
|
||||
<p>Here we'll describe how the hinting works in the libstdc++
|
||||
implementation, and what you need to do in order to take advantage of
|
||||
it. (Insertions can change from logarithmic complexity to amortized
|
||||
constant time, if the hint is properly used.) Also, since the current
|
||||
implementation is based on the SGI STL one, these points may hold true
|
||||
for other library implementations also, since the HP/SGI code is used
|
||||
in a lot of places.
|
||||
</p>
|
||||
<p>In the following text, the phrases <em>greater than</em> and <em>less
|
||||
than</em> refer to the results of the strict weak ordering imposed on
|
||||
the container by its comparison object, which defaults to (basically)
|
||||
"<". Using those phrases is semantically sloppy, but I
|
||||
didn't want to get bogged down in syntax. I assume that if you are
|
||||
intelligent enough to use your own comparison objects, you are also
|
||||
intelligent enough to assign "greater" and "lesser"
|
||||
their new meanings in the next paragraph. *grin*
|
||||
</p>
|
||||
<p>If the <code>hint</code> parameter ('p' above) is equivalent to:
|
||||
</p>
|
||||
<ul>
|
||||
<li><code>begin()</code>, then the item being inserted should have a key
|
||||
less than all the other keys in the container. The item will
|
||||
be inserted at the beginning of the container, becoming the new
|
||||
entry at <code>begin()</code>.
|
||||
</li>
|
||||
<li><code>end()</code>, then the item being inserted should have a key
|
||||
greater than all the other keys in the container. The item will
|
||||
be inserted at the end of the container, becoming the new entry
|
||||
at <code>end()</code>.
|
||||
</li>
|
||||
<li>neither <code>begin()</code> nor <code>end()</code>, then: Let <code>h</code>
|
||||
be the entry in the container pointed to by <code>hint</code>, that
|
||||
is, <code>h = *hint</code>. Then the item being inserted should have
|
||||
a key less than that of <code>h</code>, and greater than that of the
|
||||
item preceding <code>h</code>. The new item will be inserted
|
||||
between <code>h</code> and <code>h</code>'s predecessor.
|
||||
</li>
|
||||
</ul>
|
||||
<p>For <code>multimap</code> and <code>multiset</code>, the restrictions are
|
||||
slightly looser: "greater than" should be replaced by
|
||||
"not less than" and "less than" should be replaced
|
||||
by "not greater than." (Why not replace greater with
|
||||
greater-than-or-equal-to? You probably could in your head, but the
|
||||
mathematicians will tell you that it isn't the same thing.)
|
||||
</p>
|
||||
<p>If the conditions are not met, then the hint is not used, and the
|
||||
insertion proceeds as if you had called <code> a.insert(t) </code>
|
||||
instead. (<strong>Note </strong> that GCC releases prior to 3.0.2
|
||||
had a bug in the case with <code>hint == begin()</code> for the
|
||||
<code>map</code> and <code>set</code> classes. You should not use a hint
|
||||
argument in those releases.)
|
||||
</p>
|
||||
<p>This behavior goes well with other containers' <code>insert()</code>
|
||||
functions which take an iterator: if used, the new item will be
|
||||
inserted before the iterator passed as an argument, same as the other
|
||||
containers.
|
||||
</p>
|
||||
<p><strong>Note </strong> also that the hint in this implementation is a
|
||||
one-shot. The older insertion-with-hint routines check the immediately
|
||||
surrounding entries to ensure that the new item would in fact belong
|
||||
there. If the hint does not point to the correct place, then no
|
||||
further local searching is done; the search begins from scratch in
|
||||
logarithmic time.
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="5">Bitmasks and string arguments</a></h2>
|
||||
<p>Bitmasks do not take char* nor const char* arguments in their
|
||||
constructors. This is something of an accident, but you can read
|
||||
about the problem: follow the library's "Links" from the
|
||||
homepage, and from the C++ information "defect reflector"
|
||||
link, select the library issues list. Issue number 116 describes the
|
||||
problem.
|
||||
</p>
|
||||
<p>For now you can simply make a temporary string object using the
|
||||
constructor expression:
|
||||
</p>
|
||||
<pre>
|
||||
std::bitset<5> b ( std::string("10110") );
|
||||
</pre>
|
||||
instead of
|
||||
<pre>
|
||||
std::bitset<5> b ( "10110" ); // invalid
|
||||
</pre>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="6"><code>std::list::size()</code> is O(n)!</a></h2>
|
||||
<p>Yes it is, and that's okay. This is a decision that we preserved when
|
||||
we imported SGI's STL implementation. The following is quoted from
|
||||
<a href="http://www.sgi.com/tech/stl/FAQ.html">their FAQ</a>:
|
||||
</p>
|
||||
<blockquote>
|
||||
<p>The size() member function, for list and slist, takes time
|
||||
proportional to the number of elements in the list. This was a
|
||||
deliberate tradeoff. The only way to get a constant-time size() for
|
||||
linked lists would be to maintain an extra member variable containing
|
||||
the list's size. This would require taking extra time to update that
|
||||
variable (it would make splice() a linear time operation, for example),
|
||||
and it would also make the list larger. Many list algorithms don't
|
||||
require that extra word (algorithms that do require it might do better
|
||||
with vectors than with lists), and, when it is necessary to maintain
|
||||
an explicit size count, it's something that users can do themselves.
|
||||
</p>
|
||||
<p>This choice is permitted by the C++ standard. The standard says that
|
||||
size() "should" be constant time, and "should"
|
||||
does not mean the same thing as "shall". This is the
|
||||
officially recommended ISO wording for saying that an implementation
|
||||
is supposed to do something unless there is a good reason not to.
|
||||
</p>
|
||||
<p>One implication of linear time size(): you should never write
|
||||
</p>
|
||||
<pre>
|
||||
if (L.size() == 0)
|
||||
...</pre>
|
||||
Instead, you should write
|
||||
<pre>
|
||||
if (L.empty())
|
||||
...</pre>
|
||||
</blockquote>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="7">Space overhead management for vectors</a></h2>
|
||||
<p>In
|
||||
<a href="http://gcc.gnu.org/ml/libstdc++/2002-04/msg00105.html">this
|
||||
message to the list</a>, Daniel Kostecky announced work on an
|
||||
alternate form of <code>std::vector</code> that would support hints
|
||||
on the number of elements to be over-allocated. The design was also
|
||||
described, along with possible implementation choices.
|
||||
</p>
|
||||
<p>The first two alpha releases were announced
|
||||
<a href="http://gcc.gnu.org/ml/libstdc++/2002-07/msg00048.html">here</a>
|
||||
and
|
||||
<a href="http://gcc.gnu.org/ml/libstdc++/2002-07/msg00111.html">here</a>.
|
||||
The releases themselves are available at
|
||||
<a href="http://www.kotelna.sk/dk/sw/caphint/">
|
||||
http://www.kotelna.sk/dk/sw/caphint/</a>.
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<hr />
|
||||
<p class="fineprint"><em>
|
||||
See <a href="../17_intro/license.html">license.html</a> for copying conditions.
|
||||
Comments and suggestions are welcome, and may be sent to
|
||||
<a href="mailto:libstdc++@gcc.gnu.org">the libstdc++ mailing list</a>.
|
||||
</em></p>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,48 +0,0 @@
|
|||
|
||||
/*****************************************************************
|
||||
* Functions to help treat arrays in a uniform manner. These were
|
||||
* inspired by a thread on comp.lang.c++.moderated, started by Dietmar
|
||||
* Kuehl and contributed to by the rest of the entire planet.
|
||||
*
|
||||
* beginof (x), endof (x), lengthof (x) now accompany sizeof, where x
|
||||
* can be either a container (currently only sequences) or a builtin
|
||||
* array (/not/ a pointer). The beginof/endof are intended for use in
|
||||
* the algorithms library, and lengthof is a "sizing" function.
|
||||
*
|
||||
* Note example:
|
||||
* char an_array [17];
|
||||
* cerr << lengthof(an_array) << endl;
|
||||
* produces assembly code of
|
||||
* mov 17,register0
|
||||
* call ofstream_put
|
||||
* i.e., the template function inlining really does work; g++
|
||||
* requires -O3 (or -finline-functions) before it does this, though.
|
||||
*
|
||||
* pedwards 13Nov98
|
||||
*/
|
||||
// beginof
|
||||
template <class T>
|
||||
inline typename vector<T>::iterator beginof (vector<T> &v)
|
||||
{ return v.begin(); }
|
||||
|
||||
template <class T, unsigned int sz>
|
||||
inline T* beginof (T (&array)[sz]) { return array; }
|
||||
|
||||
|
||||
// endof
|
||||
template <class T>
|
||||
inline typename vector<T>::iterator endof (vector<T> &v)
|
||||
{ return v.end(); }
|
||||
|
||||
template <class T, unsigned int sz>
|
||||
inline T* endof (T (&array)[sz]) { return array + sz; }
|
||||
|
||||
|
||||
// lengthof
|
||||
template <class T>
|
||||
inline typename vector<T>::size_type lengthof (vector<T> &v)
|
||||
{ return v.size(); }
|
||||
|
||||
template <class T, unsigned int sz>
|
||||
inline unsigned int lengthof (T (&)[sz]) { return sz; }
|
||||
|
|
@ -1,200 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta name="AUTHOR" content="pme@gcc.gnu.org (Phil Edwards)" />
|
||||
<meta name="KEYWORDS" content="HOWTO, libstdc++, GCC, g++, libg++, STL" />
|
||||
<meta name="DESCRIPTION" content="HOWTO for the libstdc++ chapter 24." />
|
||||
<meta name="GENERATOR" content="vi and eight fingers" />
|
||||
<title>libstdc++ HOWTO: Chapter 24: Iterators</title>
|
||||
<link rel="StyleSheet" href="../lib3styles.css" type="text/css" />
|
||||
<link rel="Start" href="../documentation.html" type="text/html"
|
||||
title="GNU C++ Standard Library" />
|
||||
<link rel="Prev" href="../23_containers/howto.html" type="text/html"
|
||||
title="Containers" />
|
||||
<link rel="Next" href="../25_algorithms/howto.html" type="text/html"
|
||||
title="Algorithms" />
|
||||
<link rel="Copyright" href="../17_intro/license.html" type="text/html" />
|
||||
<link rel="Help" href="../faq/index.html" type="text/html" title="F.A.Q." />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 class="centered"><a name="top">Chapter 24: Iterators</a></h1>
|
||||
|
||||
<p>Chapter 24 deals with the FORTRAN subroutines for automatically
|
||||
transforming lemmings into gold.
|
||||
</p>
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
<hr />
|
||||
<h1>Contents</h1>
|
||||
<ul>
|
||||
<li><a href="#1">They ain't pointers!</a></li>
|
||||
<li><a href="#2">It ends <em>where?</em></a></li>
|
||||
</ul>
|
||||
|
||||
<hr />
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<h2><a name="1">They ain't pointers!</a></h2>
|
||||
<p><a href="../faq/index.html#5_1">FAQ 5.1</a> points out that iterators
|
||||
are not implemented as pointers. They are a generalization of
|
||||
pointers, but they are implemented in libstdc++ as separate classes.
|
||||
</p>
|
||||
<p>Keeping that simple fact in mind as you design your code will
|
||||
prevent a whole lot of difficult-to-understand bugs.
|
||||
</p>
|
||||
<p>You can think of it the other way 'round, even. Since iterators
|
||||
are a generalization, that means that <em>pointers</em> are
|
||||
<em>iterators</em>, and that pointers can be used whenever an
|
||||
iterator would be. All those functions in the Algorithms chapter
|
||||
of the Standard will work just as well on plain arrays and their
|
||||
pointers.
|
||||
</p>
|
||||
<p>That doesn't mean that when you pass in a pointer, it gets wrapped
|
||||
into some special delegating iterator-to-pointer class with a layer
|
||||
of overhead. (If you think that's the case anywhere, you don't
|
||||
understand templates to begin with...) Oh, no; if you pass
|
||||
in a pointer, then the compiler will instantiate that template
|
||||
using T* as a type, and good old high-speed pointer arithmetic as
|
||||
its operations, so the resulting code will be doing exactly the same
|
||||
things as it would be doing if you had hand-coded it yourself (for
|
||||
the 273rd time).
|
||||
</p>
|
||||
<p>How much overhead <em>is</em> there when using an iterator class?
|
||||
Very little. Most of the layering classes contain nothing but
|
||||
typedefs, and typedefs are "meta-information" that simply
|
||||
tell the compiler some nicknames; they don't create code. That
|
||||
information gets passed down through inheritance, so while the
|
||||
compiler has to do work looking up all the names, your runtime code
|
||||
does not. (This has been a prime concern from the beginning.)
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="2">It ends <em>where?</em></a></h2>
|
||||
<p>This starts off sounding complicated, but is actually very easy,
|
||||
especially towards the end. Trust me.
|
||||
</p>
|
||||
<p>Beginners usually have a little trouble understand the whole
|
||||
'past-the-end' thing, until they remember their early algebra classes
|
||||
(see, they <em>told</em> you that stuff would come in handy!) and
|
||||
the concept of half-open ranges.
|
||||
</p>
|
||||
<p>First, some history, and a reminder of some of the funkier rules in
|
||||
C and C++ for builtin arrays. The following rules have always been
|
||||
true for both languages:
|
||||
</p>
|
||||
<ol>
|
||||
<li>You can point anywhere in the array, <em>or to the first element
|
||||
past the end of the array</em>. A pointer that points to one
|
||||
past the end of the array is guaranteed to be as unique as a
|
||||
pointer to somewhere inside the array, so that you can compare
|
||||
such pointers safely.
|
||||
</li>
|
||||
<li>You can only dereference a pointer that points into an array.
|
||||
If your array pointer points outside the array -- even to just
|
||||
one past the end -- and you dereference it, Bad Things happen.
|
||||
</li>
|
||||
<li>Strictly speaking, simply pointing anywhere else invokes
|
||||
undefined behavior. Most programs won't puke until such a
|
||||
pointer is actually dereferenced, but the standards leave that
|
||||
up to the platform.
|
||||
</li>
|
||||
</ol>
|
||||
<p>The reason this past-the-end addressing was allowed is to make it
|
||||
easy to write a loop to go over an entire array, e.g.,
|
||||
while (*d++ = *s++);.
|
||||
</p>
|
||||
<p>So, when you think of two pointers delimiting an array, don't think
|
||||
of them as indexing 0 through n-1. Think of them as <em>boundary
|
||||
markers</em>:
|
||||
</p>
|
||||
<pre>
|
||||
|
||||
beginning end
|
||||
| |
|
||||
| | This is bad. Always having to
|
||||
| | remember to add or subtract one.
|
||||
| | Off-by-one bugs very common here.
|
||||
V V
|
||||
array of N elements
|
||||
|---|---|--...--|---|---|
|
||||
| 0 | 1 | ... |N-2|N-1|
|
||||
|---|---|--...--|---|---|
|
||||
|
||||
^ ^
|
||||
| |
|
||||
| | This is good. This is safe. This
|
||||
| | is guaranteed to work. Just don't
|
||||
| | dereference 'end'.
|
||||
beginning end
|
||||
|
||||
</pre>
|
||||
<p>See? Everything between the boundary markers is part of the array.
|
||||
Simple.
|
||||
</p>
|
||||
<p>Now think back to your junior-high school algebra course, when you
|
||||
were learning how to draw graphs. Remember that a graph terminating
|
||||
with a solid dot meant, "Everything up through this point,"
|
||||
and a graph terminating with an open dot meant, "Everything up
|
||||
to, but not including, this point," respectively called closed
|
||||
and open ranges? Remember how closed ranges were written with
|
||||
brackets, <em>[a,b]</em>, and open ranges were written with parentheses,
|
||||
<em>(a,b)</em>?
|
||||
</p>
|
||||
<p>The boundary markers for arrays describe a <em>half-open range</em>,
|
||||
starting with (and including) the first element, and ending with (but
|
||||
not including) the last element: <em>[beginning,end)</em>. See, I
|
||||
told you it would be simple in the end.
|
||||
</p>
|
||||
<p>Iterators, and everything working with iterators, follows this same
|
||||
time-honored tradition. A container's <code>begin()</code> method returns
|
||||
an iterator referring to the first element, and its <code>end()</code>
|
||||
method returns a past-the-end iterator, which is guaranteed to be
|
||||
unique and comparable against any other iterator pointing into the
|
||||
middle of the container.
|
||||
</p>
|
||||
<p>Container constructors, container methods, and algorithms, all take
|
||||
pairs of iterators describing a range of values on which to operate.
|
||||
All of these ranges are half-open ranges, so you pass the beginning
|
||||
iterator as the starting parameter, and the one-past-the-end iterator
|
||||
as the finishing parameter.
|
||||
</p>
|
||||
<p>This generalizes very well. You can operate on sub-ranges quite
|
||||
easily this way; functions accepting a <em>[first,last)</em> range
|
||||
don't know or care whether they are the boundaries of an entire {array,
|
||||
sequence, container, whatever}, or whether they only enclose a few
|
||||
elements from the center. This approach also makes zero-length
|
||||
sequences very simple to recognize: if the two endpoints compare
|
||||
equal, then the {array, sequence, container, whatever} is empty.
|
||||
</p>
|
||||
<p>Just don't dereference <code>end()</code>.
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<hr />
|
||||
<p class="fineprint"><em>
|
||||
See <a href="../17_intro/license.html">license.html</a> for copying conditions.
|
||||
Comments and suggestions are welcome, and may be sent to
|
||||
<a href="mailto:libstdc++@gcc.gnu.org">the libstdc++ mailing list</a>.
|
||||
</em></p>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,116 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta name="AUTHOR" content="pme@gcc.gnu.org (Phil Edwards)" />
|
||||
<meta name="KEYWORDS" content="HOWTO, libstdc++, GCC, g++, libg++, STL" />
|
||||
<meta name="DESCRIPTION" content="HOWTO for the libstdc++ chapter 25." />
|
||||
<meta name="GENERATOR" content="vi and eight fingers" />
|
||||
<title>libstdc++ HOWTO: Chapter 25: Algorithms</title>
|
||||
<link rel="StyleSheet" href="../lib3styles.css" type="text/css" />
|
||||
<link rel="Start" href="../documentation.html" type="text/html"
|
||||
title="GNU C++ Standard Library" />
|
||||
<link rel="Prev" href="../24_iterators/howto.html" type="text/html"
|
||||
title="Iterators" />
|
||||
<link rel="Next" href="../26_numerics/howto.html" type="text/html"
|
||||
title="Numerics" />
|
||||
<link rel="Copyright" href="../17_intro/license.html" type="text/html" />
|
||||
<link rel="Help" href="../faq/index.html" type="text/html" title="F.A.Q." />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 class="centered"><a name="top">Chapter 25: Algorithms</a></h1>
|
||||
|
||||
<p>Chapter 25 deals with the generalized subroutines for automatically
|
||||
transforming lemmings into gold.
|
||||
</p>
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
<hr />
|
||||
<h1>Contents</h1>
|
||||
<ul>
|
||||
<li><a href="#1">Prerequisites</a></li>
|
||||
<li><a href="#2">Special <code>swap</code>s</a></li>
|
||||
</ul>
|
||||
|
||||
<hr />
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<h2><a name="1">Prerequisites</a></h2>
|
||||
<p>The neatest accomplishment of the algorithms chapter is that all the
|
||||
work is done via iterators, not containers directly. This means two
|
||||
important things:
|
||||
</p>
|
||||
<ol>
|
||||
<li>Anything that behaves like an iterator can be used in one of
|
||||
these algorithms. Raw pointers make great candidates, thus
|
||||
built-in arrays are fine containers, as well as your own iterators.
|
||||
</li>
|
||||
<li>The algorithms do not (and cannot) affect the container as a
|
||||
whole; only the things between the two iterator endpoints. If
|
||||
you pass a range of iterators only enclosing the middle third of
|
||||
a container, then anything outside that range is inviolate.
|
||||
</li>
|
||||
</ol>
|
||||
<p>Even strings can be fed through the algorithms here, although the
|
||||
string class has specialized versions of many of these functions (for
|
||||
example, <code>string::find()</code>). Most of the examples on this
|
||||
page will use simple arrays of integers as a playground for
|
||||
algorithms, just to keep things simple.
|
||||
<a name="Nsize">The use of <strong>N</strong></a> as a size in the
|
||||
examples is to keep things easy to read but probably won't be valid
|
||||
code. You can use wrappers such as those described in the
|
||||
<a href="../23_containers/howto.html">containers chapter</a> to keep
|
||||
real code readable.
|
||||
</p>
|
||||
<p>The single thing that trips people up the most is the definition of
|
||||
<em>range</em> used with iterators; the famous
|
||||
"past-the-end" rule that everybody loves to hate. The
|
||||
<a href="../24_iterators/howto.html#2">iterators chapter</a> of this
|
||||
document has a complete explanation of this simple rule that seems to
|
||||
cause so much confusion. Once you get <em>range</em> into your head
|
||||
(it's not that hard, honest!), then the algorithms are a cakewalk.
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="2">Special <code>swap</code>s</a></h2>
|
||||
<p>If you call <code> std::swap(x,y); </code> where x and y are standard
|
||||
containers, then the call will automatically be replaced by a call to
|
||||
<code> x.swap(y); </code> instead.
|
||||
</p>
|
||||
<p>This allows member functions of each container class to take over, and
|
||||
containers' swap functions should have O(1) complexity according to
|
||||
the standard. (And while "should" allows implementations to
|
||||
behave otherwise and remain compliant, this implementation does in
|
||||
fact use constant-time swaps.) This should not be surprising, since
|
||||
for two containers of the same type to swap contents, only some
|
||||
internal pointers to storage need to be exchanged.
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<hr />
|
||||
<p class="fineprint"><em>
|
||||
See <a href="../17_intro/license.html">license.html</a> for copying conditions.
|
||||
Comments and suggestions are welcome, and may be sent to
|
||||
<a href="mailto:libstdc++@gcc.gnu.org">the libstdc++ mailing list</a>.
|
||||
</em></p>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,179 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta name="AUTHOR" content="pme@gcc.gnu.org (Phil Edwards)" />
|
||||
<meta name="KEYWORDS" content="HOWTO, libstdc++, GCC, g++, libg++, STL" />
|
||||
<meta name="DESCRIPTION" content="HOWTO for the libstdc++ chapter 26." />
|
||||
<meta name="GENERATOR" content="vi and eight fingers" />
|
||||
<title>libstdc++ HOWTO: Chapter 26: Numerics</title>
|
||||
<link rel="StyleSheet" href="../lib3styles.css" type="text/css" />
|
||||
<link rel="Start" href="../documentation.html" type="text/html"
|
||||
title="GNU C++ Standard Library" />
|
||||
<link rel="Prev" href="../25_algorithms/howto.html" type="text/html"
|
||||
title="Algorithms" />
|
||||
<link rel="Next" href="../27_io/howto.html" type="text/html"
|
||||
title="Input/Output" />
|
||||
<link rel="Copyright" href="../17_intro/license.html" type="text/html" />
|
||||
<link rel="Help" href="../faq/index.html" type="text/html" title="F.A.Q." />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 class="centered"><a name="top">Chapter 26: Numerics</a></h1>
|
||||
|
||||
<p>Chapter 26 deals with building block abstractions to aid in
|
||||
numerical computing:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Template data structures such as <code>valarray<></code>
|
||||
and <code>complex<></code>.
|
||||
</li>
|
||||
<li>Template numerical functions such as <code>accumulate</code>,
|
||||
<code>inner_product</code>, <code>partial_sum</code>, and
|
||||
<code>adjacent_difference</code>.
|
||||
</li>
|
||||
</ul>
|
||||
<p>All of the Standard C math functions are of course included in C++,
|
||||
and overloaded versions for <code>long</code>, <code>float</code>, and
|
||||
<code>long double</code> have been added for all of them.
|
||||
</p>
|
||||
|
||||
<!-- ####################################################### -->
|
||||
<hr />
|
||||
<h1>Contents</h1>
|
||||
<ul>
|
||||
<li><a href="#1">Complex Number Processing</a></li>
|
||||
<li><a href="#2">Array Processing</a></li>
|
||||
<li><a href="#3">Numerical Functions</a></li>
|
||||
<li><a href="#4">C99</a></li>
|
||||
</ul>
|
||||
|
||||
<hr />
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<h2><a name="1">Complex Number Processing</a></h2>
|
||||
<p>Using <code>complex<></code> becomes even more comple- er, sorry,
|
||||
<em>complicated</em>, with the not-quite-gratuitously-incompatible
|
||||
addition of complex types to the C language. David Tribble has
|
||||
compiled a list of C++98 and C99 conflict points; his description of
|
||||
C's new type versus those of C++ and how to get them playing together
|
||||
nicely is
|
||||
<a href="http://david.tribble.com/text/cdiffs.htm#C99-complex">here</a>.
|
||||
</p>
|
||||
<p><code>complex<></code> is intended to be instantiated with a
|
||||
floating-point type. As long as you meet that and some other basic
|
||||
requirements, then the resulting instantiation has all of the usual
|
||||
math operators defined, as well as definitions of <code>op<<</code>
|
||||
and <code>op>></code> that work with iostreams: <code>op<<</code>
|
||||
prints <code>(u,v)</code> and <code>op>></code> can read <code>u</code>,
|
||||
<code>(u)</code>, and <code>(u,v)</code>.
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="2">Array Processing</a></h2>
|
||||
<p>One of the major reasons why FORTRAN can chew through numbers so well
|
||||
is that it is defined to be free of pointer aliasing, an assumption
|
||||
that C89 is not allowed to make, and neither is C++98. C99 adds a new
|
||||
keyword, <code>restrict</code>, to apply to individual pointers. The
|
||||
C++ solution is contained in the library rather than the language
|
||||
(although many vendors can be expected to add this to their compilers
|
||||
as an extension).
|
||||
</p>
|
||||
<p>That library solution is a set of two classes, five template classes,
|
||||
and "a whole bunch" of functions. The classes are required
|
||||
to be free of pointer aliasing, so compilers can optimize the
|
||||
daylights out of them the same way that they have been for FORTRAN.
|
||||
They are collectively called <code>valarray</code>, although strictly
|
||||
speaking this is only one of the five template classes, and they are
|
||||
designed to be familiar to people who have worked with the BLAS
|
||||
libraries before.
|
||||
</p>
|
||||
<p>Some more stuff should go here once somebody has time to write it.
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="3">Numerical Functions</a></h2>
|
||||
<p>There are four generalized functions in the <numeric> header
|
||||
that follow the same conventions as those in <algorithm>. Each
|
||||
of them is overloaded: one signature for common default operations,
|
||||
and a second for fully general operations. Their names are
|
||||
self-explanatory to anyone who works with numerics on a regular basis:
|
||||
</p>
|
||||
<ul>
|
||||
<li><code>accumulate</code></li>
|
||||
<li><code>inner_product</code></li>
|
||||
<li><code>partial_sum</code></li>
|
||||
<li><code>adjacent_difference</code></li>
|
||||
</ul>
|
||||
<p>Here is a simple example of the two forms of <code>accumulate</code>.
|
||||
</p>
|
||||
<pre>
|
||||
int ar[50];
|
||||
int someval = somefunction();
|
||||
|
||||
// ...initialize members of ar to something...
|
||||
|
||||
int sum = std::accumulate(ar,ar+50,0);
|
||||
int sum_stuff = std::accumulate(ar,ar+50,someval);
|
||||
int product = std::accumulate(ar,ar+50,1,std::multiplies<int>());
|
||||
</pre>
|
||||
<p>The first call adds all the members of the array, using zero as an
|
||||
initial value for <code>sum</code>. The second does the same, but uses
|
||||
<code>someval</code> as the starting value (thus, <code>sum_stuff == sum +
|
||||
someval</code>). The final call uses the second of the two signatures,
|
||||
and multiplies all the members of the array; here we must obviously
|
||||
use 1 as a starting value instead of 0.
|
||||
</p>
|
||||
<p>The other three functions have similar dual-signature forms.
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="4">C99</a></h2>
|
||||
<p>In addition to the other topics on this page, we'll note here some
|
||||
of the C99 features that appear in libstdc++.
|
||||
</p>
|
||||
<p>The C99 features depend on the <code>--enable-c99</code> configure flag.
|
||||
This flag is already on by default, but it can be disabled by the
|
||||
user. Also, the configuration machinery will disable it if the
|
||||
necessary support for C99 (e.g., header files) cannot be found.
|
||||
</p>
|
||||
<p>As of GCC 3.0, C99 support includes classification functions
|
||||
such as <code>isnormal</code>, <code>isgreater</code>,
|
||||
<code>isnan</code>, etc.
|
||||
The functions used for 'long long' support such as <code>strtoll</code>
|
||||
are supported, as is the <code>lldiv_t</code> typedef. Also supported
|
||||
are the wide character functions using 'long long', like
|
||||
<code>wcstoll</code>.
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<hr />
|
||||
<p class="fineprint"><em>
|
||||
See <a href="../17_intro/license.html">license.html</a> for copying conditions.
|
||||
Comments and suggestions are welcome, and may be sent to
|
||||
<a href="mailto:libstdc++@gcc.gnu.org">the libstdc++ mailing list</a>.
|
||||
</em></p>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,51 +0,0 @@
|
|||
|
||||
From: James Kanze <kanze@gabi-soft.de>
|
||||
Newsgroups: comp.lang.c++.moderated
|
||||
Subject: Re: binary iostreams ?
|
||||
Date: 3 Feb 2001 14:28:19 -0500
|
||||
Message-ID: <86lmro86qp.fsf@alex.gabi-soft.de>
|
||||
|
||||
"Plinio Conti" <plinio.contiNO@SPAMMINGmclink.it> writes:
|
||||
|
||||
|> Why std c++ library stream classes are only text-oriented?
|
||||
|
||||
Because that is the only universally recognized format.
|
||||
|
||||
|> I mean, if I want to write an int, a float, etc. AS IT IS I can't
|
||||
|> use streams, because they write and read a human readable text
|
||||
|> format of numbers.
|
||||
|
||||
Correct.
|
||||
|
||||
|> Does anyone know how to solve the problem?
|
||||
|
||||
It depends on what you really want to do. If you are just dumping a
|
||||
block of memory to disk, in order to free up memory, and will reread it
|
||||
later in the same run of the same program, ostream::write and
|
||||
istream::read are what you need. Note, however, that this ony works 1)
|
||||
in the same run of the same program, and 2) for PODs without pointers.
|
||||
|
||||
If you are writing something that will be read by another program, or a
|
||||
later run of the same program, you'll have to define a specific format
|
||||
to use, and implement streams to input and output that. If you are
|
||||
writing something that will be read by an existing program, or be
|
||||
transmitted over a network to another machine, you will have to find out
|
||||
what protocol is expected, and adher to it.
|
||||
|
||||
|> Any public library?
|
||||
|
||||
Not that I know of. I think that there is a library somewhere that
|
||||
outputs in format RPC, or maybe some Internet format.
|
||||
|
||||
|> What do you think about this choice?
|
||||
|
||||
What other choice is possible? It's not reasonable to ask the standard
|
||||
to support all binary formats, and it's not reasonable for it to favor
|
||||
any one of them. Given that, what else can you do.
|
||||
|
||||
--
|
||||
James Kanze mailto:kanze@gabi-soft.de
|
||||
Conseils en informatique orientée objet/
|
||||
Beratung in objektorientierter Datenverarbeitung
|
||||
Ziegelhüttenweg 17a, 60598 Frankfurt, Germany Tel. +49(069)63198627
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
|
||||
From: kuehl@ramsen.informatik.uni-konstanz.de (Dietmar Kuehl)
|
||||
Newsgroups: comp.std.c++
|
||||
Subject: Re: binary iostreams ?
|
||||
Date: Sat, 3 Feb 2001 17:17:49 GMT
|
||||
Message-ID: <95hctq$suu$2@news.BelWue.DE>
|
||||
|
||||
Hi,
|
||||
Plinio Conti (plinio.contiNO@SPAMMINGmclink.it) wrote:
|
||||
: Why std c++ library stream classes are only text-oriented?
|
||||
|
||||
There is only a text oriented front end to stream buffers because text
|
||||
input and output does not vary between platforms. This is very
|
||||
different for binary output. For example, binary output has to consider
|
||||
|
||||
- word sizes: Is an 'int' two, four, or eight bytes long? The same
|
||||
questions arise for all other built-in types.
|
||||
|
||||
- what is the bit pattern of a value? I think that at least implicitly
|
||||
in the standard a binary representation for integer types is required.
|
||||
I don't think that it is required to use two's complement. In any
|
||||
case, the floating point representations do differ, eg. in their
|
||||
number of bytes used.
|
||||
|
||||
- what "endianess" is to be used?
|
||||
|
||||
Basically it is possible to decide a format for each of those. This,
|
||||
however, implies inefficient implementations on platforms where the
|
||||
format does not match the internal representation.
|
||||
|
||||
What many people asking for binary I/O forget is that binary I/O also
|
||||
requires some form of formatting! Assuming that just writing data and
|
||||
then reading it in will work is asking for problems, eg. when the
|
||||
compiler version changes and they decided to use a 32 bit integer
|
||||
rather than a 16 bit integer: It is not even necessary to switch
|
||||
platforms to run into problems!
|
||||
|
||||
: I mean, if I want to write an int, a float, etc. AS IT IS I can't use
|
||||
: streams, because they write and read a human readable text format of
|
||||
: numbers.
|
||||
|
||||
Which is for most I/O a reasonable approach. If it is not for you, you
|
||||
might want to consider a data base: File I/O is not really useful as a
|
||||
persistance mechanism. It is fine eg. for user interaction (text I/O),
|
||||
logging (text I/O), cross platfrom program interaction (formatted I/O),
|
||||
and data exchange (formatted I/O). In all these cases, the I/O is
|
||||
formatted, although possible using a binary format. For persistance,
|
||||
data bases are used. Depending on your needs, a relational or an object
|
||||
oriented one may be better suited.
|
||||
|
||||
That said, it is worth to mention that it is easy to create a hierarchy
|
||||
similar to IOStreams built on top of stream buffers but doing binary
|
||||
formatting. A somewhat aged example is found at
|
||||
<ftp://ftp.fmi.uni-konstanz.de/pub/algo/personal/kuehl/binio.tar.gz>.
|
||||
This uses XDR formatting of the binary data (well, if I remmeber
|
||||
correctly, it is easy to plug in a different binary formatting).
|
||||
|
||||
: Does anyone know how to solve the problem?
|
||||
|
||||
Use a data base, text formatting, or binary formatting. With the
|
||||
details you have given it is impossible to tell which of those is the
|
||||
right approach because you haven't told *why* you want a binary format
|
||||
and *what* you want to do. That basically means that you came up with
|
||||
solution and you want us to confirm that it is the right one without
|
||||
telling us what problem is solved! Until I have seen the problem I
|
||||
doubt that binary I/O is the right approach...
|
||||
|
||||
... and, BTW, using 'std::istream::read()' and 'std::ostream::write()'
|
||||
is almost certainly the *wrong* approach! These functions are an
|
||||
historical mistake which should have been corrected in the standard:
|
||||
It is my understanding that these methods were present in the IOStream
|
||||
version predating the rework from Jerry Schwartz and were left in to
|
||||
be compatible with the earlier stuff although they were not necessary:
|
||||
You could get binary I/O from the stream buffer level. The original
|
||||
IOStream library (maybe you remember using <stream.h>) did not have
|
||||
stream buffers and thus basic support for binary I/O was also present
|
||||
on the streams level.
|
||||
|
||||
: What do you think about this choice?
|
||||
|
||||
When I wrote the above paragraph about confirming your choice, I haven't
|
||||
read this question! As I said above: You told us what solution you have
|
||||
choosen without stating what problem is solved. We cannot determine
|
||||
whether your choice is the right one. Actually, I'm pretty sure it is
|
||||
the wrong one but without seen the details I can't be certain.
|
||||
--
|
||||
<mailto:dietmar_kuehl@yahoo.com> <http://www.dietmar-kuehl.de/>
|
||||
Phaidros eaSE - Easy Software Engineering: <http://www.phaidros.com/>
|
||||
|
|
@ -1,779 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta name="AUTHOR" content="pme@gcc.gnu.org (Phil Edwards)" />
|
||||
<meta name="KEYWORDS" content="HOWTO, libstdc++, GCC, g++, libg++, STL" />
|
||||
<meta name="DESCRIPTION" content="HOWTO for the libstdc++ chapter 27." />
|
||||
<meta name="GENERATOR" content="vi and eight fingers" />
|
||||
<title>libstdc++ HOWTO: Chapter 27: Input/Output</title>
|
||||
<link rel="StyleSheet" href="../lib3styles.css" type="text/css" />
|
||||
<link rel="Start" href="../documentation.html" type="text/html"
|
||||
title="GNU C++ Standard Library" />
|
||||
<link rel="Prev" href="../26_numerics/howto.html" type="text/html"
|
||||
title="Numerics" />
|
||||
<link rel="Next" href="../ext/howto.html" type="text/html"
|
||||
title="Extensions" />
|
||||
<link rel="Copyright" href="../17_intro/license.html" type="text/html" />
|
||||
<link rel="Help" href="../faq/index.html" type="text/html" title="F.A.Q." />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 class="centered"><a name="top">Chapter 27: Input/Output</a></h1>
|
||||
|
||||
<p>Chapter 27 deals with iostreams and all their subcomponents
|
||||
and extensions. All <em>kinds</em> of fun stuff.
|
||||
</p>
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
<hr />
|
||||
<h1>Contents</h1>
|
||||
<ul>
|
||||
<li><a href="#1">Copying a file</a></li>
|
||||
<li><a href="#2">The buffering is screwing up my program!</a></li>
|
||||
<li><a href="#3">Binary I/O</a></li>
|
||||
<li><a href="#5">What is this <sstream>/stringstreams thing?</a></li>
|
||||
<li><a href="#6">Deriving a stream buffer</a></li>
|
||||
<li><a href="#7">More on binary I/O</a></li>
|
||||
<li><a href="#8">Pathetic performance? Ditch C.</a></li>
|
||||
<li><a href="#9">Threads and I/O</a></li>
|
||||
<li><a href="#10">Which header?</a></li>
|
||||
<li><a href="#11">Using FILE*s and file descriptors with IOStreams</a></li>
|
||||
</ul>
|
||||
|
||||
<hr />
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<h2><a name="1">Copying a file</a></h2>
|
||||
<p>So you want to copy a file quickly and easily, and most important,
|
||||
completely portably. And since this is C++, you have an open
|
||||
ifstream (call it IN) and an open ofstream (call it OUT):
|
||||
</p>
|
||||
<pre>
|
||||
#include <fstream>
|
||||
|
||||
std::ifstream IN ("input_file");
|
||||
std::ofstream OUT ("output_file"); </pre>
|
||||
<p>Here's the easiest way to get it completely wrong:
|
||||
</p>
|
||||
<pre>
|
||||
OUT << IN;</pre>
|
||||
<p>For those of you who don't already know why this doesn't work
|
||||
(probably from having done it before), I invite you to quickly
|
||||
create a simple text file called "input_file" containing
|
||||
the sentence
|
||||
</p>
|
||||
<pre>
|
||||
The quick brown fox jumped over the lazy dog.</pre>
|
||||
<p>surrounded by blank lines. Code it up and try it. The contents
|
||||
of "output_file" may surprise you.
|
||||
</p>
|
||||
<p>Seriously, go do it. Get surprised, then come back. It's worth it.
|
||||
</p>
|
||||
<hr width="60%" />
|
||||
<p>The thing to remember is that the <code>basic_[io]stream</code> classes
|
||||
handle formatting, nothing else. In particular, they break up on
|
||||
whitespace. The actual reading, writing, and storing of data is
|
||||
handled by the <code>basic_streambuf</code> family. Fortunately, the
|
||||
<code>operator<<</code> is overloaded to take an ostream and
|
||||
a pointer-to-streambuf, in order to help with just this kind of
|
||||
"dump the data verbatim" situation.
|
||||
</p>
|
||||
<p>Why a <em>pointer</em> to streambuf and not just a streambuf? Well,
|
||||
the [io]streams hold pointers (or references, depending on the
|
||||
implementation) to their buffers, not the actual
|
||||
buffers. This allows polymorphic behavior on the part of the buffers
|
||||
as well as the streams themselves. The pointer is easily retrieved
|
||||
using the <code>rdbuf()</code> member function. Therefore, the easiest
|
||||
way to copy the file is:
|
||||
</p>
|
||||
<pre>
|
||||
OUT << IN.rdbuf();</pre>
|
||||
<p>So what <em>was</em> happening with OUT<<IN? Undefined
|
||||
behavior, since that particular << isn't defined by the Standard.
|
||||
I have seen instances where it is implemented, but the character
|
||||
extraction process removes all the whitespace, leaving you with no
|
||||
blank lines and only "Thequickbrownfox...". With
|
||||
libraries that do not define that operator, IN (or one of IN's
|
||||
member pointers) sometimes gets converted to a void*, and the output
|
||||
file then contains a perfect text representation of a hexadecimal
|
||||
address (quite a big surprise). Others don't compile at all.
|
||||
</p>
|
||||
<p>Also note that none of this is specific to o<b>*f*</b>streams.
|
||||
The operators shown above are all defined in the parent
|
||||
basic_ostream class and are therefore available with all possible
|
||||
descendants.
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="2">The buffering is screwing up my program!</a></h2>
|
||||
<!--
|
||||
This is not written very well. I need to redo this section.
|
||||
-->
|
||||
<p>First, are you sure that you understand buffering? Particularly
|
||||
the fact that C++ may not, in fact, have anything to do with it?
|
||||
</p>
|
||||
<p>The rules for buffering can be a little odd, but they aren't any
|
||||
different from those of C. (Maybe that's why they can be a bit
|
||||
odd.) Many people think that writing a newline to an output
|
||||
stream automatically flushes the output buffer. This is true only
|
||||
when the output stream is, in fact, a terminal and not a file
|
||||
or some other device -- and <em>that</em> may not even be true
|
||||
since C++ says nothing about files nor terminals. All of that is
|
||||
system-dependent. (The "newline-buffer-flushing only occurring
|
||||
on terminals" thing is mostly true on Unix systems, though.)
|
||||
</p>
|
||||
<p>Some people also believe that sending <code>endl</code> down an
|
||||
output stream only writes a newline. This is incorrect; after a
|
||||
newline is written, the buffer is also flushed. Perhaps this
|
||||
is the effect you want when writing to a screen -- get the text
|
||||
out as soon as possible, etc -- but the buffering is largely
|
||||
wasted when doing this to a file:
|
||||
</p>
|
||||
<pre>
|
||||
output << "a line of text" << endl;
|
||||
output << some_data_variable << endl;
|
||||
output << "another line of text" << endl; </pre>
|
||||
<p>The proper thing to do in this case to just write the data out
|
||||
and let the libraries and the system worry about the buffering.
|
||||
If you need a newline, just write a newline:
|
||||
</p>
|
||||
<pre>
|
||||
output << "a line of text\n"
|
||||
<< some_data_variable << '\n'
|
||||
<< "another line of text\n"; </pre>
|
||||
<p>I have also joined the output statements into a single statement.
|
||||
You could make the code prettier by moving the single newline to
|
||||
the start of the quoted text on the last line, for example.
|
||||
</p>
|
||||
<p>If you do need to flush the buffer above, you can send an
|
||||
<code>endl</code> if you also need a newline, or just flush the buffer
|
||||
yourself:
|
||||
</p>
|
||||
<pre>
|
||||
output << ...... << flush; // can use std::flush manipulator
|
||||
output.flush(); // or call a member fn </pre>
|
||||
<p>On the other hand, there are times when writing to a file should
|
||||
be like writing to standard error; no buffering should be done
|
||||
because the data needs to appear quickly (a prime example is a
|
||||
log file for security-related information). The way to do this is
|
||||
just to turn off the buffering <em>before any I/O operations at
|
||||
all</em> have been done (note that opening counts as an I/O operation):
|
||||
</p>
|
||||
<pre>
|
||||
std::ofstream os;
|
||||
std::ifstream is;
|
||||
int i;
|
||||
|
||||
os.rdbuf()->pubsetbuf(0,0);
|
||||
is.rdbuf()->pubsetbuf(0,0);
|
||||
|
||||
os.open("/foo/bar/baz");
|
||||
is.open("/qux/quux/quuux");
|
||||
...
|
||||
os << "this data is written immediately\n";
|
||||
is >> i; // and this will probably cause a disk read </pre>
|
||||
<p>Since all aspects of buffering are handled by a streambuf-derived
|
||||
member, it is necessary to get at that member with <code>rdbuf()</code>.
|
||||
Then the public version of <code>setbuf</code> can be called. The
|
||||
arguments are the same as those for the Standard C I/O Library
|
||||
function (a buffer area followed by its size).
|
||||
</p>
|
||||
<p>A great deal of this is implementation-dependent. For example,
|
||||
<code>streambuf</code> does not specify any actions for its own
|
||||
<code>setbuf()</code>-ish functions; the classes derived from
|
||||
<code>streambuf</code> each define behavior that "makes
|
||||
sense" for that class: an argument of (0,0) turns off buffering
|
||||
for <code>filebuf</code> but does nothing at all for its siblings
|
||||
<code>stringbuf</code> and <code>strstreambuf</code>, and specifying
|
||||
anything other than (0,0) has varying effects.
|
||||
User-defined classes derived from <code>streambuf</code> can
|
||||
do whatever they want. (For <code>filebuf</code> and arguments for
|
||||
<code>(p,s)</code> other than zeros, libstdc++ does what you'd expect:
|
||||
the first <code>s</code> bytes of <code>p</code> are used as a buffer,
|
||||
which you must allocate and deallocate.)
|
||||
</p>
|
||||
<p>A last reminder: there are usually more buffers involved than
|
||||
just those at the language/library level. Kernel buffers, disk
|
||||
buffers, and the like will also have an effect. Inspecting and
|
||||
changing those are system-dependent.
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="3">Binary I/O</a></h2>
|
||||
<p>The first and most important thing to remember about binary I/O is
|
||||
that opening a file with <code>ios::binary</code> is not, repeat
|
||||
<em>not</em>, the only thing you have to do. It is not a silver
|
||||
bullet, and will not allow you to use the <code><</>></code>
|
||||
operators of the normal fstreams to do binary I/O.
|
||||
</p>
|
||||
<p>Sorry. Them's the breaks.
|
||||
</p>
|
||||
<p>This isn't going to try and be a complete tutorial on reading and
|
||||
writing binary files (because "binary"
|
||||
<a href="#7">covers a lot of ground)</a>, but we will try and clear
|
||||
up a couple of misconceptions and common errors.
|
||||
</p>
|
||||
<p>First, <code>ios::binary</code> has exactly one defined effect, no more
|
||||
and no less. Normal text mode has to be concerned with the newline
|
||||
characters, and the runtime system will translate between (for
|
||||
example) '\n' and the appropriate end-of-line sequence (LF on Unix,
|
||||
CRLF on DOS, CR on Macintosh, etc). (There are other things that
|
||||
normal mode does, but that's the most obvious.) Opening a file in
|
||||
binary mode disables this conversion, so reading a CRLF sequence
|
||||
under Windows won't accidentally get mapped to a '\n' character, etc.
|
||||
Binary mode is not supposed to suddenly give you a bitstream, and
|
||||
if it is doing so in your program then you've discovered a bug in
|
||||
your vendor's compiler (or some other part of the C++ implementation,
|
||||
possibly the runtime system).
|
||||
</p>
|
||||
<p>Second, using <code><<</code> to write and <code>>></code> to
|
||||
read isn't going to work with the standard file stream classes, even
|
||||
if you use <code>skipws</code> during reading. Why not? Because
|
||||
ifstream and ofstream exist for the purpose of <em>formatting</em>,
|
||||
not reading and writing. Their job is to interpret the data into
|
||||
text characters, and that's exactly what you don't want to happen
|
||||
during binary I/O.
|
||||
</p>
|
||||
<p>Third, using the <code>get()</code> and <code>put()/write()</code> member
|
||||
functions still aren't guaranteed to help you. These are
|
||||
"unformatted" I/O functions, but still character-based.
|
||||
(This may or may not be what you want, see below.)
|
||||
</p>
|
||||
<p>Notice how all the problems here are due to the inappropriate use
|
||||
of <em>formatting</em> functions and classes to perform something
|
||||
which <em>requires</em> that formatting not be done? There are a
|
||||
seemingly infinite number of solutions, and a few are listed here:
|
||||
</p>
|
||||
<ul>
|
||||
<li>"Derive your own fstream-type classes and write your own
|
||||
<</>> operators to do binary I/O on whatever data
|
||||
types you're using." This is a Bad Thing, because while
|
||||
the compiler would probably be just fine with it, other humans
|
||||
are going to be confused. The overloaded bitshift operators
|
||||
have a well-defined meaning (formatting), and this breaks it.
|
||||
</li>
|
||||
<li>"Build the file structure in memory, then <code>mmap()</code>
|
||||
the file and copy the structure." Well, this is easy to
|
||||
make work, and easy to break, and is pretty equivalent to
|
||||
using <code>::read()</code> and <code>::write()</code> directly, and
|
||||
makes no use of the iostream library at all...
|
||||
</li>
|
||||
<li>"Use streambufs, that's what they're there for."
|
||||
While not trivial for the beginner, this is the best of all
|
||||
solutions. The streambuf/filebuf layer is the layer that is
|
||||
responsible for actual I/O. If you want to use the C++
|
||||
library for binary I/O, this is where you start.
|
||||
</li>
|
||||
</ul>
|
||||
<p>How to go about using streambufs is a bit beyond the scope of this
|
||||
document (at least for now), but while streambufs go a long way,
|
||||
they still leave a couple of things up to you, the programmer.
|
||||
As an example, byte ordering is completely between you and the
|
||||
operating system, and you have to handle it yourself.
|
||||
</p>
|
||||
<p>Deriving a streambuf or filebuf
|
||||
class from the standard ones, one that is specific to your data
|
||||
types (or an abstraction thereof) is probably a good idea, and
|
||||
lots of examples exist in journals and on Usenet. Using the
|
||||
standard filebufs directly (either by declaring your own or by
|
||||
using the pointer returned from an fstream's <code>rdbuf()</code>)
|
||||
is certainly feasible as well.
|
||||
</p>
|
||||
<p>One area that causes problems is trying to do bit-by-bit operations
|
||||
with filebufs. C++ is no different from C in this respect: I/O
|
||||
must be done at the byte level. If you're trying to read or write
|
||||
a few bits at a time, you're going about it the wrong way. You
|
||||
must read/write an integral number of bytes and then process the
|
||||
bytes. (For example, the streambuf functions take and return
|
||||
variables of type <code>int_type</code>.)
|
||||
</p>
|
||||
<p>Another area of problems is opening text files in binary mode.
|
||||
Generally, binary mode is intended for binary files, and opening
|
||||
text files in binary mode means that you now have to deal with all of
|
||||
those end-of-line and end-of-file problems that we mentioned before.
|
||||
An instructive thread from comp.lang.c++.moderated delved off into
|
||||
this topic starting more or less at
|
||||
<a href="http://groups.google.com/groups?oi=djq&selm=an_436187505">this</a>
|
||||
article and continuing to the end of the thread. (You'll have to
|
||||
sort through some flames every couple of paragraphs, but the points
|
||||
made are good ones.)
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="5">What is this <sstream>/stringstreams thing?</a></h2>
|
||||
<p>Stringstreams (defined in the header <code><sstream></code>)
|
||||
are in this author's opinion one of the coolest things since
|
||||
sliced time. An example of their use is in the Received Wisdom
|
||||
section for Chapter 21 (Strings),
|
||||
<a href="../21_strings/howto.html#1.1internal"> describing how to
|
||||
format strings</a>.
|
||||
</p>
|
||||
<p>The quick definition is: they are siblings of ifstream and ofstream,
|
||||
and they do for <code>std::string</code> what their siblings do for
|
||||
files. All that work you put into writing <code><<</code> and
|
||||
<code>>></code> functions for your classes now pays off
|
||||
<em>again!</em> Need to format a string before passing the string
|
||||
to a function? Send your stuff via <code><<</code> to an
|
||||
ostringstream. You've read a string as input and need to parse it?
|
||||
Initialize an istringstream with that string, and then pull pieces
|
||||
out of it with <code>>></code>. Have a stringstream and need to
|
||||
get a copy of the string inside? Just call the <code>str()</code>
|
||||
member function.
|
||||
</p>
|
||||
<p>This only works if you've written your
|
||||
<code><<</code>/<code>>></code> functions correctly, though,
|
||||
and correctly means that they take istreams and ostreams as
|
||||
parameters, not i<b>f</b>streams and o<b>f</b>streams. If they
|
||||
take the latter, then your I/O operators will work fine with
|
||||
file streams, but with nothing else -- including stringstreams.
|
||||
</p>
|
||||
<p>If you are a user of the strstream classes, you need to update
|
||||
your code. You don't have to explicitly append <code>ends</code> to
|
||||
terminate the C-style character array, you don't have to mess with
|
||||
"freezing" functions, and you don't have to manage the
|
||||
memory yourself. The strstreams have been officially deprecated,
|
||||
which means that 1) future revisions of the C++ Standard won't
|
||||
support them, and 2) if you use them, people will laugh at you.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="6">Deriving a stream buffer</a></h2>
|
||||
<p>Creating your own stream buffers for I/O can be remarkably easy.
|
||||
If you are interested in doing so, we highly recommend two very
|
||||
excellent books:
|
||||
<a href="http://www.langer.camelot.de/iostreams.html">Standard C++
|
||||
IOStreams and Locales</a> by Langer and Kreft, ISBN 0-201-18395-1, and
|
||||
<a href="http://www.josuttis.com/libbook/">The C++ Standard Library</a>
|
||||
by Nicolai Josuttis, ISBN 0-201-37926-0. Both are published by
|
||||
Addison-Wesley, who isn't paying us a cent for saying that, honest.
|
||||
</p>
|
||||
<p>Here is a simple example, io/outbuf1, from the Josuttis text. It
|
||||
transforms everything sent through it to uppercase. This version
|
||||
assumes many things about the nature of the character type being
|
||||
used (for more information, read the books or the newsgroups):
|
||||
</p>
|
||||
<pre>
|
||||
#include <iostream>
|
||||
#include <streambuf>
|
||||
#include <locale>
|
||||
#include <cstdio>
|
||||
|
||||
class outbuf : public std::streambuf
|
||||
{
|
||||
protected:
|
||||
/* central output function
|
||||
* - print characters in uppercase mode
|
||||
*/
|
||||
virtual int_type overflow (int_type c) {
|
||||
if (c != EOF) {
|
||||
// convert lowercase to uppercase
|
||||
c = std::toupper(static_cast<char>(c),getloc());
|
||||
|
||||
// and write the character to the standard output
|
||||
if (putchar(c) == EOF) {
|
||||
return EOF;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
// create special output buffer
|
||||
outbuf ob;
|
||||
// initialize output stream with that output buffer
|
||||
std::ostream out(&ob);
|
||||
|
||||
out << "31 hexadecimal: "
|
||||
<< std::hex << 31 << std::endl;
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
<p>Try it yourself! More examples can be found in 3.1.x code, in
|
||||
<code>include/ext/*_filebuf.h</code>, and on
|
||||
<a href="http://www.informatik.uni-konstanz.de/~kuehl/c++/iostream/">Dietmar
|
||||
Kühl's IOStreams page</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="7">More on binary I/O</a></h2>
|
||||
<p>Towards the beginning of February 2001, the subject of
|
||||
"binary" I/O was brought up in a couple of places at the
|
||||
same time. One notable place was Usenet, where James Kanze and
|
||||
Dietmar Kühl separately posted articles on why attempting
|
||||
generic binary I/O was not a good idea. (Here are copies of
|
||||
<a href="binary_iostreams_kanze.txt">Kanze's article</a> and
|
||||
<a href="binary_iostreams_kuehl.txt">Kühl's article</a>.)
|
||||
</p>
|
||||
<p>Briefly, the problems of byte ordering and type sizes mean that
|
||||
the unformatted functions like <code>ostream::put()</code> and
|
||||
<code>istream::get()</code> cannot safely be used to communicate
|
||||
between arbitrary programs, or across a network, or from one
|
||||
invocation of a program to another invocation of the same program
|
||||
on a different platform, etc.
|
||||
</p>
|
||||
<p>The entire Usenet thread is instructive, and took place under the
|
||||
subject heading "binary iostreams" on both comp.std.c++
|
||||
and comp.lang.c++.moderated in parallel. Also in that thread,
|
||||
Dietmar Kühl mentioned that he had written a pair of stream
|
||||
classes that would read and write XDR, which is a good step towards
|
||||
a portable binary format.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="8">Pathetic performance? Ditch C.</a></h2>
|
||||
<p>It sounds like a flame on C, but it isn't. Really. Calm down.
|
||||
I'm just saying it to get your attention.
|
||||
</p>
|
||||
<p>Because the C++ library includes the C library, both C-style and
|
||||
C++-style I/O have to work at the same time. For example:
|
||||
</p>
|
||||
<pre>
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
|
||||
std::cout << "Hel";
|
||||
std::printf ("lo, worl");
|
||||
std::cout << "d!\n";
|
||||
</pre>
|
||||
<p>This must do what you think it does.
|
||||
</p>
|
||||
<p>Alert members of the audience will immediately notice that buffering
|
||||
is going to make a hash of the output unless special steps are taken.
|
||||
</p>
|
||||
<p>The special steps taken by libstdc++, at least for version 3.0,
|
||||
involve doing very little buffering for the standard streams, leaving
|
||||
most of the buffering to the underlying C library. (This kind of
|
||||
thing is tricky to get right.)
|
||||
The upside is that correctness is ensured. The downside is that
|
||||
writing through <code>cout</code> can quite easily lead to awful
|
||||
performance when the C++ I/O library is layered on top of the C I/O
|
||||
library (as it is for 3.0 by default). Some patches have been applied
|
||||
which improve the situation for 3.1.
|
||||
</p>
|
||||
<p>However, the C and C++ standard streams only need to be kept in sync
|
||||
when both libraries' facilities are in use. If your program only uses
|
||||
C++ I/O, then there's no need to sync with the C streams. The right
|
||||
thing to do in this case is to call
|
||||
</p>
|
||||
<pre>
|
||||
#include <em>any of the I/O headers such as ios, iostream, etc</em>
|
||||
|
||||
std::ios::sync_with_stdio(false);
|
||||
</pre>
|
||||
<p>You must do this before performing any I/O via the C++ stream objects.
|
||||
Once you call this, the C++ streams will operate independently of the
|
||||
(unused) C streams. For GCC 3.x, this means that <code>cout</code> and
|
||||
company will become fully buffered on their own.
|
||||
</p>
|
||||
<p>Note, by the way, that the synchronization requirement only applies to
|
||||
the standard streams (<code>cin</code>, <code>cout</code>,
|
||||
<code>cerr</code>,
|
||||
<code>clog</code>, and their wide-character counterparts). File stream
|
||||
objects that you declare yourself have no such requirement and are fully
|
||||
buffered.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="9">Threads and I/O</a></h2>
|
||||
<p>I'll assume that you have already read the
|
||||
<a href="../17_intro/howto.html#3">general notes on library threads</a>,
|
||||
and the
|
||||
<a href="../23_containers/howto.html#3">notes on threaded container
|
||||
access</a> (you might not think of an I/O stream as a container, but
|
||||
the points made there also hold here). If you have not read them,
|
||||
please do so first.
|
||||
</p>
|
||||
<p>This gets a bit tricky. Please read carefully, and bear with me.
|
||||
</p>
|
||||
<h3>Structure</h3>
|
||||
<p>A wrapper
|
||||
type called <code>__basic_file</code> provides our abstraction layer
|
||||
for the <code>std::filebuf</code> classes. Nearly all decisions dealing
|
||||
with actual input and output must be made in <code>__basic_file</code>.
|
||||
</p>
|
||||
<p>A generic locking mechanism is somewhat in place at the filebuf layer,
|
||||
but is not used in the current code. Providing locking at any higher
|
||||
level is akin to providing locking within containers, and is not done
|
||||
for the same reasons (see the links above).
|
||||
</p>
|
||||
<h3>The defaults for 3.0.x</h3>
|
||||
<p>The __basic_file type is simply a collection of small wrappers around
|
||||
the C stdio layer (again, see the link under Structure). We do no
|
||||
locking ourselves, but simply pass through to calls to <code>fopen</code>,
|
||||
<code>fwrite</code>, and so forth.
|
||||
</p>
|
||||
<p>So, for 3.0, the question of "is multithreading safe for I/O"
|
||||
must be answered with, "is your platform's C library threadsafe
|
||||
for I/O?" Some are by default, some are not; many offer multiple
|
||||
implementations of the C library with varying tradeoffs of threadsafety
|
||||
and efficiency. You, the programmer, are always required to take care
|
||||
with multiple threads.
|
||||
</p>
|
||||
<p>(As an example, the POSIX standard requires that C stdio FILE*
|
||||
operations are atomic. POSIX-conforming C libraries (e.g, on Solaris
|
||||
and GNU/Linux) have an internal mutex to serialize operations on
|
||||
FILE*s. However, you still need to not do stupid things like calling
|
||||
<code>fclose(fs)</code> in one thread followed by an access of
|
||||
<code>fs</code> in another.)
|
||||
</p>
|
||||
<p>So, if your platform's C library is threadsafe, then your
|
||||
<code>fstream</code> I/O operations will be threadsafe at the lowest
|
||||
level. For higher-level operations, such as manipulating the data
|
||||
contained in the stream formatting classes (e.g., setting up callbacks
|
||||
inside an <code>std::ofstream</code>), you need to guard such accesses
|
||||
like any other critical shared resource.
|
||||
</p>
|
||||
<h3>The future</h3>
|
||||
<p> A
|
||||
second choice may be available for I/O implementations: libio. This is
|
||||
disabled by default, and in fact will not currently work due to other
|
||||
issues. It will be revisited, however.
|
||||
</p>
|
||||
<p>The libio code is a subset of the guts of the GNU libc (glibc) I/O
|
||||
implementation. When libio is in use, the <code>__basic_file</code>
|
||||
type is basically derived from FILE. (The real situation is more
|
||||
complex than that... it's derived from an internal type used to
|
||||
implement FILE. See libio/libioP.h to see scary things done with
|
||||
vtbls.) The result is that there is no "layer" of C stdio
|
||||
to go through; the filebuf makes calls directly into the same
|
||||
functions used to implement <code>fread</code>, <code>fwrite</code>,
|
||||
and so forth, using internal data structures. (And when I say
|
||||
"makes calls directly," I mean the function is literally
|
||||
replaced by a jump into an internal function. Fast but frightening.
|
||||
*grin*)
|
||||
</p>
|
||||
<p>Also, the libio internal locks are used. This requires pulling in
|
||||
large chunks of glibc, such as a pthreads implementation, and is one
|
||||
of the issues preventing widespread use of libio as the libstdc++
|
||||
cstdio implementation.
|
||||
</p>
|
||||
<p>But we plan to make this work, at least as an option if not a future
|
||||
default. Platforms running a copy of glibc with a recent-enough
|
||||
version will see calls from libstdc++ directly into the glibc already
|
||||
installed. For other platforms, a copy of the libio subsection will
|
||||
be built and included in libstdc++.
|
||||
</p>
|
||||
<h3>Alternatives</h3>
|
||||
<p>Don't forget that other cstdio implementations are possible. You could
|
||||
easily write one to perform your own forms of locking, to solve your
|
||||
"interesting" problems.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="10">Which header?</a></h2>
|
||||
<p>To minimize the time you have to wait on the compiler, it's good to
|
||||
only include the headers you really need. Many people simply include
|
||||
<iostream> when they don't need to -- and that can <em>penalize
|
||||
your runtime as well.</em> Here are some tips on which header to use
|
||||
for which situations, starting with the simplest.
|
||||
</p>
|
||||
<p><strong><iosfwd></strong> should be included whenever you simply
|
||||
need the <em>name</em> of an I/O-related class, such as
|
||||
"ofstream" or "basic_streambuf". Like the name
|
||||
implies, these are forward declarations. (A word to all you fellow
|
||||
old school programmers: trying to forward declare classes like
|
||||
"class istream;" won't work. Look in the iosfwd header if
|
||||
you'd like to know why.) For example,
|
||||
</p>
|
||||
<pre>
|
||||
#include <iosfwd>
|
||||
|
||||
class MyClass
|
||||
{
|
||||
....
|
||||
std::ifstream& input_file;
|
||||
};
|
||||
|
||||
extern std::ostream& operator<< (std::ostream&, MyClass&);
|
||||
</pre>
|
||||
<p><strong><ios></strong> declares the base classes for the entire
|
||||
I/O stream hierarchy, std::ios_base and std::basic_ios<charT>, the
|
||||
counting types std::streamoff and std::streamsize, the file
|
||||
positioning type std::fpos, and the various manipulators like
|
||||
std::hex, std::fixed, std::noshowbase, and so forth.
|
||||
</p>
|
||||
<p>The ios_base class is what holds the format flags, the state flags,
|
||||
and the functions which change them (setf(), width(), precision(),
|
||||
etc). You can also store extra data and register callback functions
|
||||
through ios_base, but that has been historically underused. Anything
|
||||
which doesn't depend on the type of characters stored is consolidated
|
||||
here.
|
||||
</p>
|
||||
<p>The template class basic_ios is the highest template class in the
|
||||
hierarchy; it is the first one depending on the character type, and
|
||||
holds all general state associated with that type: the pointer to the
|
||||
polymorphic stream buffer, the facet information, etc.
|
||||
</p>
|
||||
<p><strong><streambuf></strong> declares the template class
|
||||
basic_streambuf, and two standard instantiations, streambuf and
|
||||
wstreambuf. If you need to work with the vastly useful and capable
|
||||
stream buffer classes, e.g., to create a new form of storage
|
||||
transport, this header is the one to include.
|
||||
</p>
|
||||
<p><strong><istream></strong>/<strong><ostream></strong> are
|
||||
the headers to include when you are using the >>/<<
|
||||
interface, or any of the other abstract stream formatting functions.
|
||||
For example,
|
||||
</p>
|
||||
<pre>
|
||||
#include <istream>
|
||||
|
||||
std::ostream& operator<< (std::ostream& os, MyClass& c)
|
||||
{
|
||||
return os << c.data1() << c.data2();
|
||||
}
|
||||
</pre>
|
||||
<p>The std::istream and std::ostream classes are the abstract parents of
|
||||
the various concrete implementations. If you are only using the
|
||||
interfaces, then you only need to use the appropriate interface header.
|
||||
</p>
|
||||
<p><strong><iomanip></strong> provides "extractors and inserters
|
||||
that alter information maintained by class ios_base and its derived
|
||||
classes," such as std::setprecision and std::setw. If you need
|
||||
to write expressions like <code>os << setw(3);</code> or
|
||||
<code>is >> setbase(8);</code>, you must include <iomanip>.
|
||||
</p>
|
||||
<p><strong><sstream></strong>/<strong><fstream></strong>
|
||||
declare the six stringstream and fstream classes. As they are the
|
||||
standard concrete descendants of istream and ostream, you will already
|
||||
know about them.
|
||||
</p>
|
||||
<p>Finally, <strong><iostream></strong> provides the eight standard
|
||||
global objects (cin, cout, etc). To do this correctly, this header
|
||||
also provides the contents of the <istream> and <ostream>
|
||||
headers, but nothing else. The contents of this header look like
|
||||
</p>
|
||||
<pre>
|
||||
#include <ostream>
|
||||
#include <istream>
|
||||
|
||||
namespace std
|
||||
{
|
||||
extern istream cin;
|
||||
extern ostream cout;
|
||||
....
|
||||
|
||||
// this is explained below
|
||||
<strong>static ios_base::Init __foo;</strong> // not its real name
|
||||
}
|
||||
</pre>
|
||||
<p>Now, the runtime penalty mentioned previously: the global objects
|
||||
must be initialized before any of your own code uses them; this is
|
||||
guaranteed by the standard. Like any other global object, they must
|
||||
be initialized once and only once. This is typically done with a
|
||||
construct like the one above, and the nested class ios_base::Init is
|
||||
specified in the standard for just this reason.
|
||||
</p>
|
||||
<p>How does it work? Because the header is included before any of your
|
||||
code, the <strong>__foo</strong> object is constructed before any of
|
||||
your objects. (Global objects are built in the order in which they
|
||||
are declared, and destroyed in reverse order.) The first time the
|
||||
constructor runs, the eight stream objects are set up.
|
||||
</p>
|
||||
<p>The <code>static</code> keyword means that each object file compiled
|
||||
from a source file containing <iostream> will have its own
|
||||
private copy of <strong>__foo</strong>. There is no specified order
|
||||
of construction across object files (it's one of those pesky NP
|
||||
problems that make life so interesting), so one copy in each object
|
||||
file means that the stream objects are guaranteed to be set up before
|
||||
any of your code which uses them could run, thereby meeting the
|
||||
requirements of the standard.
|
||||
</p>
|
||||
<p>The penalty, of course, is that after the first copy of
|
||||
<strong>__foo</strong> is constructed, all the others are just wasted
|
||||
processor time. The time spent is merely for an increment-and-test
|
||||
inside a function call, but over several dozen or hundreds of object
|
||||
files, that time can add up. (It's not in a tight loop, either.)
|
||||
</p>
|
||||
<p>The lesson? Only include <iostream> when you need to use one of
|
||||
the standard objects in that source file; you'll pay less startup
|
||||
time. Only include the header files you need to in general; your
|
||||
compile times will go down when there's less parsing work to do.
|
||||
</p>
|
||||
|
||||
|
||||
<hr />
|
||||
<h2><a name="11">Using FILE*s and file descriptors with IOStreams</a></h2>
|
||||
<!-- referenced by ext/howto.html#2, update link if numbering changes -->
|
||||
<p>The v2 library included non-standard extensions to construct
|
||||
<code>std::filebuf</code>s from C stdio types such as
|
||||
<code>FILE*</code>s and POSIX file descriptors.
|
||||
Today the recommended way to use stdio types with libstdc++
|
||||
IOStreams is via the <code>stdio_filebuf</code> class (see below),
|
||||
but earlier releases provided slightly different mechanisms.
|
||||
</p>
|
||||
<ul>
|
||||
<li>3.0.x <code>filebuf</code>s have another ctor with this signature:
|
||||
<br />
|
||||
<code>basic_filebuf(__c_file_type*, ios_base::openmode, int_type);</code>
|
||||
<br />This comes in very handy in a number of places, such as
|
||||
attaching Unix sockets, pipes, and anything else which uses file
|
||||
descriptors, into the IOStream buffering classes. The three
|
||||
arguments are as follows:
|
||||
<ul>
|
||||
<li><code>__c_file_type* F </code>
|
||||
// the __c_file_type typedef usually boils down to stdio's FILE
|
||||
</li>
|
||||
<li><code>ios_base::openmode M </code>
|
||||
// same as all the other uses of openmode
|
||||
</li>
|
||||
<li><code>int_type B </code>
|
||||
// buffer size, defaults to BUFSIZ if not specified
|
||||
</li>
|
||||
</ul>
|
||||
For those wanting to use file descriptors instead of FILE*'s, I
|
||||
invite you to contemplate the mysteries of C's <code>fdopen()</code>.
|
||||
</li>
|
||||
<li>In library snapshot 3.0.95 and later, <code>filebuf</code>s bring
|
||||
back an old extension: the <code>fd()</code> member function. The
|
||||
integer returned from this function can be used for whatever file
|
||||
descriptors can be used for on your platform. Naturally, the
|
||||
library cannot track what you do on your own with a file descriptor,
|
||||
so if you perform any I/O directly, don't expect the library to be
|
||||
aware of it.
|
||||
</li>
|
||||
<li>Beginning with 3.1, the extra <code>filebuf</code> constructor and
|
||||
the <code>fd()</code> function were removed from the standard
|
||||
filebuf. Instead, <code><ext/stdio_filebuf.h></code> contains
|
||||
a derived class called
|
||||
<a href="http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/class____gnu__cxx_1_1stdio__filebuf.html"><code>__gnu_cxx::stdio_filebuf</code></a>.
|
||||
This class can be constructed from a C <code>FILE*</code> or a file
|
||||
descriptor, and provides the <code>fd()</code> function.
|
||||
</li>
|
||||
</ul>
|
||||
<p>If you want to access a <code>filebuf</code>'s file descriptor to
|
||||
implement file locking (e.g. using the <code>fcntl()</code> system
|
||||
call) then you might be interested in Henry Suter's
|
||||
<a href="http://suter.home.cern.ch/suter/RWLock.html">RWLock</a>
|
||||
class.
|
||||
</p>
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<hr />
|
||||
<p class="fineprint"><em>
|
||||
See <a href="../17_intro/license.html">license.html</a> for copying conditions.
|
||||
Comments and suggestions are welcome, and may be sent to
|
||||
<a href="mailto:libstdc++@gcc.gnu.org">the libstdc++ mailing list</a>.
|
||||
</em></p>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
3
libstdc++-v3/doc/html/README
Normal file
3
libstdc++-v3/doc/html/README
Normal file
|
@ -0,0 +1,3 @@
|
|||
The HTML documentation in this folder is generated from the XML sources.
|
||||
|
||||
To change or edit, please edit the XML sources in the ../xml directory.
|
|
@ -1,342 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta name="AUTHOR" content="pme@gcc.gnu.org (Phil Edwards)" />
|
||||
<meta name="KEYWORDS" content="libstdc++, libstdc++, GCC, g++" />
|
||||
<meta name="DESCRIPTION" content="Configuration options for libstdc++." />
|
||||
<meta name="GENERATOR" content="vi and eight fingers" />
|
||||
<title>libstdc++ configure options</title>
|
||||
<link rel="StyleSheet" href="lib3styles.css" type="text/css" />
|
||||
<link rel="Copyright" href="17_intro/license.html" type="text/html" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 class="centered"><a name="top">Interesting <code>configure</code>
|
||||
options</a></h1>
|
||||
|
||||
<p class="fineprint"><em>
|
||||
The latest version of this document is always available at
|
||||
<a href="http://gcc.gnu.org/onlinedocs/libstdc++/configopts.html">
|
||||
http://gcc.gnu.org/onlinedocs/libstdc++/configopts.html</a>.
|
||||
</em></p>
|
||||
|
||||
<p><em>
|
||||
To the <a href="http://gcc.gnu.org/libstdc++/">libstdc++ homepage</a>.
|
||||
</em></p>
|
||||
|
||||
<!-- ####################################################### -->
|
||||
<hr />
|
||||
<p>Here are some of the non-obvious options to libstdc++'s configure.
|
||||
Keep in mind that
|
||||
<!-- This SECnn should be the "Choosing Package Options" section. -->
|
||||
<a href="http://www.gnu.org/software/autoconf/manual/autoconf-2.57/html_node/autoconf_131.html#SEC131">they
|
||||
all have opposite forms as well</a>
|
||||
(enable/disable and with/without). The defaults are for <strong>current
|
||||
development sources</strong>, which may be different than those for
|
||||
released versions.
|
||||
</p>
|
||||
<p>The canonical way to find out the configure options that are
|
||||
available for a given set of libstdc++ sources is to go to the
|
||||
source directory and then type:<code> ./configure --help</code>
|
||||
</p>
|
||||
|
||||
<dl>
|
||||
<dt><code>--enable-multilib </code>[default]</dt>
|
||||
<dd><p>This is part of the generic multilib support for building cross
|
||||
compilers. As such, targets like "powerpc-elf" will have
|
||||
libstdc++ built many different ways: "-msoft-float"
|
||||
and not, etc. A different libstdc++ will be built for each of
|
||||
the different multilib versions. This option is on by default.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt><code>--enable-sjlj-exceptions </code></dt>
|
||||
<dd><p>Forces old, set-jump/long-jump exception handling model. If
|
||||
at all possible, the new, frame unwinding exception handling routines
|
||||
should be used instead, as they significantly reduce both
|
||||
runtime memory usage and executable size. This option can
|
||||
change the library ABI.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt><code>--enable-version-specific-runtime-libs </code></dt>
|
||||
<dd><p>Specify that run-time libraries should be installed in the
|
||||
compiler-specific subdirectory (i.e.,
|
||||
<code>${libdir}/gcc-lib/${target_alias}/${gcc_version}</code>)
|
||||
instead of <code>${libdir}</code>. This option is useful if you
|
||||
intend to use several versions of gcc in parallel. In addition,
|
||||
libstdc++'s include files will be installed in
|
||||
<code>${libdir}/gcc-lib/${target_alias}/${gcc_version}/include/g++</code>,
|
||||
unless you also specify
|
||||
<code>--with-gxx-include-dir=<em>dirname</em></code> during configuration.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt><code>--with-gxx-include-dir=<include-files dir></code></dt>
|
||||
<dd><p>Adds support for named libstdc++ include directory. For instance,
|
||||
the following puts all the libstdc++ headers into a directory
|
||||
called "2.97-20001008" instead of the usual
|
||||
"c++/(version)".
|
||||
</p>
|
||||
<pre>
|
||||
--with-gxx-include-dir=/foo/H-x86-gcc-3-c-gxx-inc/include/2.97-20001008</pre> </dd>
|
||||
|
||||
<dt><code>--enable-cstdio </code></dt>
|
||||
<dd><p>This is an abbreviated form of <code>'--enable-cstdio=stdio'</code>
|
||||
(described next). This option can change the library ABI.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt><code>--enable-cstdio=OPTION </code></dt>
|
||||
<dd><p>Select a target-specific I/O package. At the moment, the only
|
||||
choice is to use 'stdio', a generic "C" abstraction.
|
||||
The default is 'stdio'.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt><code>--enable-clocale </code></dt>
|
||||
<dd><p>This is an abbreviated form of <code>'--enable-clocale=generic'</code>
|
||||
(described next). This option can change the library ABI.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt><code>--enable-clocale=OPTION </code></dt>
|
||||
<dd><p>Select a target-specific underlying locale package. The
|
||||
choices are 'ieee_1003.1-2001' to specify an X/Open, Standard Unix
|
||||
(IEEE Std. 1003.1-2001) model based on langinfo/iconv/catgets,
|
||||
'gnu' to specify a model based on functionality from the GNU C
|
||||
library (langinfo/iconv/gettext) (from <a
|
||||
href="http://sources.redhat.com/glibc/">glibc</a>, the GNU C
|
||||
library), or 'generic' to use a generic "C"
|
||||
abstraction which consists of "C" locale info.
|
||||
</p>
|
||||
|
||||
<p>As part of the configuration process, the "C" library is
|
||||
probed both for sufficient vintage, and installed locale
|
||||
data. If either of these elements are not present, the C++
|
||||
locale model default to 'generic.' On glibc-based systems of
|
||||
version 2.2.5 and above with installed locale files, 'gnu' is
|
||||
automatically selected.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt><code>--enable-libstdcxx-allocator </code></dt>
|
||||
<dd><p>This is an abbreviated form of
|
||||
<code>'--enable-libstdcxx-allocator=auto'</code> (described
|
||||
next). This option can change the library ABI.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt><code>--enable-libstdcxx-allocator=OPTION </code></dt>
|
||||
<dd><p>Select a target-specific underlying std::allocator. The
|
||||
choices are 'new' to specify a wrapper for new, 'malloc' to
|
||||
specify a wrapper for malloc, 'mt' for a fixed power of two allocator
|
||||
(<a href="ext/mt_allocator.html">documented</a> under extensions),
|
||||
'pool' for the SGI pooled allocator or 'bitmap' for a bitmap allocator.
|
||||
This option can change the library ABI.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt><code>--enable-cheaders=OPTION </code></dt>
|
||||
<dd><p>This allows the user to define the approach taken for C header
|
||||
compatibility with C++. Options are c, c_std, and c_global.
|
||||
These correspond to the source directory's include/c,
|
||||
include/c_std, and include/c_global, and may also include
|
||||
include/c_compatibility. The default is c_global.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt><code>--enable-threads </code></dt>
|
||||
<dd><p>This is an abbreviated form of <code>'--enable-threads=yes'</code>
|
||||
(described next). This option can change the library ABI.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt><code>--enable-threads=OPTION </code></dt>
|
||||
<dd><p>Select a threading library. A full description is given in the
|
||||
general <a href="http://gcc.gnu.org/install/configure.html">compiler
|
||||
configuration instructions</a>.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt><code>--enable-libstdcxx-debug </code></dt>
|
||||
<dd><p>Build separate debug libraries in addition to what is normally built.
|
||||
By default, the debug libraries are compiled with
|
||||
<code> CXXFLAGS='-g3 -O0'</code>
|
||||
, are installed in <code>${libdir}/debug</code>, and have the
|
||||
same names and versioning information as the non-debug
|
||||
libraries. This option is off by default.
|
||||
</p>
|
||||
<p>Note this make command, executed in
|
||||
the build directory, will do much the same thing, without the
|
||||
configuration difference and without building everything twice:
|
||||
<code>make CXXFLAGS='-g3 -O0' all</code>
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt><code>--enable-libstdcxx-debug-flags=FLAGS</code></dt>
|
||||
|
||||
<dd><p>This option is only valid when <code> --enable-debug </code>
|
||||
is also specified, and applies to the debug builds only. With
|
||||
this option, you can pass a specific string of flags to the
|
||||
compiler to use when building the debug versions of libstdc++.
|
||||
FLAGS is a quoted string of options, like
|
||||
</p>
|
||||
<pre>
|
||||
--enable-libstdcxx-debug-flags='-g3 -O1 -gdwarf-2'</pre>
|
||||
</dd>
|
||||
|
||||
<dt><code>--enable-cxx-flags=FLAGS</code></dt>
|
||||
<dd><p>With this option, you can pass a string of -f (functionality)
|
||||
flags to the compiler to use when building libstdc++. This
|
||||
option can change the library ABI. FLAGS is a quoted string of
|
||||
options, like
|
||||
</p>
|
||||
<pre>
|
||||
--enable-cxx-flags='-fvtable-gc -fomit-frame-pointer -ansi'</pre>
|
||||
<p>
|
||||
Note that the flags don't necessarily have to all be -f flags,
|
||||
as shown, but usually those are the ones that will make sense
|
||||
for experimentation and configure-time overriding.
|
||||
</p>
|
||||
<p>The advantage of --enable-cxx-flags over setting CXXFLAGS in
|
||||
the 'make' environment is that, if files are automatically
|
||||
rebuilt, the same flags will be used when compiling those files
|
||||
as well, so that everything matches.
|
||||
</p>
|
||||
<p>Fun flags to try might include combinations of
|
||||
</p>
|
||||
<pre>
|
||||
-fstrict-aliasing
|
||||
-fno-exceptions
|
||||
-ffunction-sections
|
||||
-fvtable-gc</pre>
|
||||
<p>and opposite forms (-fno-) of the same. Tell us (the libstdc++
|
||||
mailing list) if you discover more!
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt><code>--enable-c99 </code></dt>
|
||||
<dd><p>The "long long" type was introduced in C99, along
|
||||
with many other functions for wide characters, and math
|
||||
classification macros, etc. If enabled, all C99 functions not
|
||||
specified by the C++ standard will be put into <code>namespace
|
||||
__gnu_cxx</code>, and then all these names will
|
||||
be injected into namespace std, so that C99 functions can be
|
||||
used "as if" they were in the C++ standard (as they
|
||||
will eventually be in some future revision of the standard,
|
||||
without a doubt). By default, C99 support is on, assuming the
|
||||
configure probes find all the necessary functions and bits
|
||||
necessary. This option can change the library ABI.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt><code>--enable-wchar_t </code>[default]</dt>
|
||||
<dd><p>Template specializations for the "wchar_t" type are
|
||||
required for wide character conversion support. Disabling
|
||||
wide character specializations may be expedient for initial
|
||||
porting efforts, but builds only a subset of what is required by
|
||||
ISO, and is not recommended. By default, this option is on.
|
||||
This option can change the library ABI.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt><code>--enable-long-long </code></dt>
|
||||
<dd><p>The "long long" type was introduced in C99. It is
|
||||
provided as a GNU extension to C++98 in g++. This flag builds
|
||||
support for "long long" into the library (specialized
|
||||
templates and the like for iostreams). This option is on by default:
|
||||
if enabled, users will have to either use the new-style "C"
|
||||
headers by default (i.e., <cmath> not <math.h>)
|
||||
or add appropriate compile-time flags to all compile lines to
|
||||
allow "C" visibility of this feature (on GNU/Linux,
|
||||
the flag is -D_ISOC99_SOURCE, which is added automatically via
|
||||
CPLUSPLUS_CPP_SPEC's addition of _GNU_SOURCE).
|
||||
This option can change the library ABI.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt><code>--enable-fully-dynamic-string </code></dt>
|
||||
<dd><p>This option enables a special version of basic_string avoiding
|
||||
the optimization that allocates empty objects in static memory.
|
||||
Mostly useful together with shared memory allocators, see PR
|
||||
libstdc++/16612 for details.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt><code>--enable-concept-checks </code></dt>
|
||||
<dd><p>This turns on additional compile-time checks for instantiated
|
||||
library templates, in the form of specialized templates,
|
||||
<a href="19_diagnostics/howto.html#3">described here</a>. They
|
||||
can help users discover when they break the rules of the STL, before
|
||||
their programs run.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt><code>--enable-symvers[=style] </code></dt>
|
||||
|
||||
<dd><p>In 3.1 and later, tries to turn on symbol versioning in the
|
||||
shared library (if a shared library has been
|
||||
requested). Values for 'style' that are currently supported
|
||||
are 'gnu', 'gnu-versioned-namespace', 'darwin', and
|
||||
'darwin-export'. Both gnu- options require that a recent
|
||||
version of the GNU linker be in use. Both darwin options are
|
||||
equivalent. With no style given, the configure script will try
|
||||
to guess correct defaults for the host system, probe to see if
|
||||
additional requirements are necessary and present for
|
||||
activation, and if so, will turn symbol versioning on. This
|
||||
option can change the library ABI.
|
||||
</p>
|
||||
|
||||
</dd>
|
||||
|
||||
<dt><code>--enable-visibility </code></dt>
|
||||
<dd><p> In 4.2 and later, enables or disables visibility attributes.
|
||||
If enabled (as by default), and the compiler seems capable of
|
||||
passing the simple sanity checks thrown at it, adjusts items
|
||||
in namespace std, namespace std::tr1, and namespace __gnu_cxx
|
||||
so that -fvisibility options work.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt><code>--enable-libstdcxx-pch </code></dt>
|
||||
<dd><p>In 3.4 and later, tries to turn on the generation of
|
||||
stdc++.h.gch, a pre-compiled file including all the standard
|
||||
C++ includes. If enabled (as by default), and the compiler
|
||||
seems capable of passing the simple sanity checks thrown at
|
||||
it, try to build stdc++.h.gch as part of the make process.
|
||||
In addition, this generated file is used later on (by appending <code>
|
||||
--include bits/stdc++.h </code> to CXXFLAGS) when running the
|
||||
testsuite.
|
||||
</p>
|
||||
</dd>
|
||||
|
||||
<dt><code>--disable-hosted-libstdcxx </code></dt>
|
||||
<dd><p>By default, a complete <em>hosted</em> C++ library is built. The
|
||||
C++ Standard also describes a <em>freestanding</em> environment,
|
||||
in which only a minimal set of headers are provided. This option
|
||||
builds such an environment.
|
||||
</p>
|
||||
</dd>
|
||||
</dl>
|
||||
<p>Return <a href="#top">to the top of the page</a> or
|
||||
<a href="http://gcc.gnu.org/libstdc++/">to the libstdc++ homepage</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<hr />
|
||||
<p class="fineprint"><em>
|
||||
See <a href="17_intro/license.html">license.html</a> for copying conditions.
|
||||
Comments and suggestions are welcome, and may be sent to
|
||||
<a href="mailto:libstdc++@gcc.gnu.org">the libstdc++ mailing list</a>.
|
||||
</em></p>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,474 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta name="AUTHOR" content="bkoz@gcc.gnu.org (Benjamin Kosnik)" />
|
||||
<meta name="KEYWORDS" content="c++, libstdc++, gdb, g++, debug" />
|
||||
<meta name="DESCRIPTION" content="Debugging C++ binaries" />
|
||||
<meta name="GENERATOR" content="vi and ten fingers" />
|
||||
<title>Debugging schemes and strategies</title>
|
||||
<link rel="StyleSheet" href="lib3styles.css" type="text/css" />
|
||||
<link rel="Copyright" href="17_intro/license.html" type="text/html" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 class="centered"><a name="top">Debugging schemes and strategies</a></h1>
|
||||
|
||||
<p class="fineprint"><em>
|
||||
The latest version of this document is always available at
|
||||
<a href="http://gcc.gnu.org/onlinedocs/libstdc++/debug.html">
|
||||
http://gcc.gnu.org/onlinedocs/libstdc++/debug.html</a>.
|
||||
</em></p>
|
||||
|
||||
<p><em>
|
||||
To the <a href="http://gcc.gnu.org/libstdc++/">libstdc++ homepage</a>.
|
||||
</em></p>
|
||||
|
||||
<!-- ####################################################### -->
|
||||
<hr />
|
||||
<p>There are numerous things that can be done to improve the ease with
|
||||
which C++ binaries are debugged when using the GNU
|
||||
tool chain. Here are some of them.
|
||||
</p>
|
||||
|
||||
<h3 class="left"><a name="gplusplus">Compiler flags determine debug info</a></h3>
|
||||
<p>The default optimizations and debug flags for a libstdc++ build are
|
||||
<code>-g -O2</code>. However, both debug and optimization flags can
|
||||
be varied to change debugging characteristics. For instance,
|
||||
turning off all optimization via the <code>-g -O0</code> flag will
|
||||
disable inlining, so that stepping through all functions, including
|
||||
inlined constructors and destructors, is possible. In addition,
|
||||
<code>-fno-eliminate-unused-debug-types</code> can be used when
|
||||
additional debug information, such as nested class info, is desired.
|
||||
</p>
|
||||
|
||||
<p>Or, the debug format that the compiler and debugger use to communicate
|
||||
information about source constructs can be changed via <code>
|
||||
-gdwarf-2 </code> or <code> -gstabs </code> flags: some debugging
|
||||
formats permit more expressive type and scope information to be
|
||||
shown in gdb. The default debug information for a particular
|
||||
platform can be identified via the value set by the
|
||||
PREFERRED_DEBUGGING_TYPE macro in the gcc sources.
|
||||
</p>
|
||||
|
||||
<p>Many other options are available: please see
|
||||
<a href="http://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html#Debugging%20Options">"Options for Debugging Your Program"</a>
|
||||
in Using the GNU Compiler Collection (GCC) for a complete list.
|
||||
</p>
|
||||
|
||||
<h3 class="left"><a name="lib">Using special flags to make a debug binary</a></h3>
|
||||
<p>If you would like debug symbols in libstdc++, there are two ways to
|
||||
build libstdc++ with debug flags. The first is to run make from the
|
||||
toplevel in a freshly-configured tree with
|
||||
</p>
|
||||
<pre>
|
||||
--enable-libstdcxx-debug
|
||||
</pre>
|
||||
<p>and perhaps</p>
|
||||
<pre>
|
||||
--enable-libstdcxx-debug-flags='...'
|
||||
</pre>
|
||||
<p>to create a separate debug build. Both the normal build and the
|
||||
debug build will persist, without having to specify
|
||||
<code>CXXFLAGS</code>, and the debug library will be installed in a
|
||||
separate directory tree, in <code>(prefix)/lib/debug</code>. For
|
||||
more information, look at the <a href="configopts.html">configuration
|
||||
options</a> document.
|
||||
</p>
|
||||
|
||||
<p>A second approach is to use the configuration flags
|
||||
</p>
|
||||
<pre>
|
||||
make CXXFLAGS='-g3 -O0' all
|
||||
</pre>
|
||||
|
||||
<p>This quick and dirty approach is often sufficient for quick
|
||||
debugging tasks, when you cannot or don't want to recompile your
|
||||
application to use the <a href="#safe">debug mode</a>.</p>
|
||||
|
||||
<h3 class="left"><a name="safe">The libstdc++ debug mode</a></h3>
|
||||
<p>By default, libstdc++ is built with efficiency in mind, and
|
||||
therefore performs little or no error checking that is not required
|
||||
by the C++ standard. This means that programs that incorrectly use
|
||||
the C++ standard library will exhibit behavior that is not portable
|
||||
and may not even be predictable, because they tread into
|
||||
implementation-specific or undefined behavior. To detect some of
|
||||
these errors before they can become problematic, libstdc++ offers a
|
||||
debug mode that provides additional checking of library facilities,
|
||||
and will report errors in the use of libstdc++ as soon as they can
|
||||
be detected by emitting a description of the problem to standard
|
||||
error and aborting the program. This debug mode is available with
|
||||
GCC 3.4.0 and later versions. </p>
|
||||
|
||||
<p>The libstdc++ debug mode performs checking for many areas of the C++
|
||||
standard, but the focus is on checking interactions among standard
|
||||
iterators, containers, and algorithms, including:</p>
|
||||
|
||||
<ul>
|
||||
<li><em>Safe iterators</em>: Iterators keep track of the
|
||||
container whose elements they reference, so errors such as
|
||||
incrementing a past-the-end iterator or dereferencing an iterator
|
||||
that points to a container that has been destructed are diagnosed
|
||||
immediately.</li>
|
||||
|
||||
<li><em>Algorithm preconditions</em>: Algorithms attempt to
|
||||
validate their input parameters to detect errors as early as
|
||||
possible. For instance, the <code>set_intersection</code>
|
||||
algorithm requires that its iterator
|
||||
parameters <code>first1</code> and <code>last1</code> form a valid
|
||||
iterator range, and that the sequence
|
||||
[<code>first1</code>, <code>last1</code>) is sorted according to
|
||||
the same predicate that was passed
|
||||
to <code>set_intersection</code>; the libstdc++ debug mode will
|
||||
detect an error if the sequence is not sorted or was sorted by a
|
||||
different predicate.</li>
|
||||
</ul>
|
||||
|
||||
<h4 class="left">Using the libstdc++ debug mode</h4>
|
||||
<p>To use the libstdc++ debug mode, compile your application with the
|
||||
compiler flag <code>-D_GLIBCXX_DEBUG</code>. Note that this flag
|
||||
changes the sizes and behavior of standard class templates such
|
||||
as <code>std::vector</code>, and therefore you can only link code
|
||||
compiled with debug mode and code compiled without debug mode if no
|
||||
instantiation of a container is passed between the two translation
|
||||
units.</p>
|
||||
|
||||
<p>By default, error messages are formatted to fit on lines of about
|
||||
78 characters. The environment variable
|
||||
<code>GLIBCXX_DEBUG_MESSAGE_LENGTH</code> can be used to request a
|
||||
different length.</p>
|
||||
|
||||
<p>For information about the design of the libstdc++ debug mode,
|
||||
please see the <a href="debug_mode.html">libstdc++ debug mode design
|
||||
document</a>.</p>
|
||||
|
||||
<h4 class="left">Using the debugging containers without debug
|
||||
mode</h4>
|
||||
<p>When it is not feasible to recompile your entire application, or
|
||||
only specific containers need checking, debugging containers are
|
||||
available as GNU extensions. These debugging containers are
|
||||
functionally equivalent to the standard drop-in containers used in
|
||||
debug mode, but they are available in a separate namespace as GNU
|
||||
extensions and may be used in programs compiled with either release
|
||||
mode or with debug mode. The
|
||||
following table provides the names and headers of the debugging
|
||||
containers:
|
||||
</p>
|
||||
|
||||
<table title="Debugging containers" border="1">
|
||||
<tr>
|
||||
<th>Container</th>
|
||||
<th>Header</th>
|
||||
<th>Debug container</th>
|
||||
<th>Debug header</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>std::bitset</td>
|
||||
<td><bitset></td>
|
||||
<td>__gnu_debug::bitset</td>
|
||||
<td><debug/bitset></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>std::deque</td>
|
||||
<td><deque></td>
|
||||
<td>__gnu_debug::deque</td>
|
||||
<td><debug/deque></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>std::list</td>
|
||||
<td><list></td>
|
||||
<td>__gnu_debug::list</td>
|
||||
<td><debug/list></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>std::map</td>
|
||||
<td><map></td>
|
||||
<td>__gnu_debug::map</td>
|
||||
<td><debug/map></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>std::multimap</td>
|
||||
<td><map></td>
|
||||
<td>__gnu_debug::multimap</td>
|
||||
<td><debug/map></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>std::multiset</td>
|
||||
<td><set></td>
|
||||
<td>__gnu_debug::multiset</td>
|
||||
<td><debug/set></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>std::set</td>
|
||||
<td><set></td>
|
||||
<td>__gnu_debug::set</td>
|
||||
<td><debug/set></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>std::string</td>
|
||||
<td><string></td>
|
||||
<td>__gnu_debug::string</td>
|
||||
<td><debug/string></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>std::wstring</td>
|
||||
<td><string></td>
|
||||
<td>__gnu_debug::wstring</td>
|
||||
<td><debug/string></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>std::basic_string</td>
|
||||
<td><string></td>
|
||||
<td>__gnu_debug::basic_string</td>
|
||||
<td><debug/string></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>std::vector</td>
|
||||
<td><vector></td>
|
||||
<td>__gnu_debug::vector</td>
|
||||
<td><debug/vector></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>In addition, when compiling in C++0x mode, these additional
|
||||
containers have additional debug capability.
|
||||
</p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>std::unordered_map</td>
|
||||
<td><unordered_map></td>
|
||||
<td>__gnu_debug::unordered_map</td>
|
||||
<td><debug/unordered_map></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>std::unordered_multimap</td>
|
||||
<td><unordered_map></td>
|
||||
<td>__gnu_debug::unordered_multimap</td>
|
||||
<td><debug/unordered_map></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>std::unordered_set</td>
|
||||
<td><unordered_set></td>
|
||||
<td>__gnu_debug::unordered_set</td>
|
||||
<td><debug/unordered_set></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>std::unordered_multiset</td>
|
||||
<td><unordered_set></td>
|
||||
<td>__gnu_debug::unordered_multiset</td>
|
||||
<td><debug/unordered_set></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h4 class="left">Debug mode semantics</h4>
|
||||
<p>A program that uses the C++ standard library correctly
|
||||
will maintain the same semantics under debug mode as it had with
|
||||
the normal (release) library. All functional and exception-handling
|
||||
guarantees made by the normal library also hold for the debug mode
|
||||
library, with one exception: performance guarantees made by the
|
||||
normal library may not hold in the debug mode library. For
|
||||
instance, erasing an element in a <code>std::list</code> is a
|
||||
constant-time operation in normal library, but in debug mode it is
|
||||
linear in the number of iterators that reference that particular
|
||||
list. So while your (correct) program won't change its results, it
|
||||
is likely to execute more slowly.</p>
|
||||
|
||||
<p>libstdc++ includes many extensions to the C++ standard library. In
|
||||
some cases the extensions are obvious, such as the hashed
|
||||
associative containers, whereas other extensions give predictable
|
||||
results to behavior that would otherwise be undefined, such as
|
||||
throwing an exception when a <code>std::basic_string</code> is
|
||||
constructed from a NULL character pointer. This latter category also
|
||||
includes implementation-defined and unspecified semantics, such as
|
||||
the growth rate of a vector. Use of these extensions is not
|
||||
considered incorrect, so code that relies on them will not be
|
||||
rejected by debug mode. However, use of these extensions may affect
|
||||
the portability of code to other implementations of the C++ standard
|
||||
library, and is therefore somewhat hazardous. For this reason, the
|
||||
libstdc++ debug mode offers a "pedantic" mode (similar to
|
||||
GCC's <code>-pedantic</code> compiler flag) that attempts to emulate
|
||||
the semantics guaranteed by the C++ standard. For
|
||||
instance, constructing a <code>std::basic_string</code> with a NULL
|
||||
character pointer would result in an exception under normal mode or
|
||||
non-pedantic debug mode (this is a libstdc++ extension), whereas
|
||||
under pedantic debug mode libstdc++ would signal an error. To enable
|
||||
the pedantic debug mode, compile your program with
|
||||
both <code>-D_GLIBCXX_DEBUG</code>
|
||||
and <code>-D_GLIBCXX_DEBUG_PEDANTIC</code> .
|
||||
(N.B. In GCC 3.4.x and 4.0.0, due to a bug,
|
||||
<code>-D_GLIBXX_DEBUG_PEDANTIC</code> was also needed. The problem has
|
||||
been fixed in GCC 4.0.1 and later versions.) </p>
|
||||
|
||||
<p>The following library components provide extra debugging
|
||||
capabilities in debug mode:</p>
|
||||
<ul>
|
||||
<li><code>std::basic_string</code> (no safe iterators and see note below)</li>
|
||||
<li><code>std::bitset</code></li>
|
||||
<li><code>std::deque</code></li>
|
||||
<li><code>std::list</code></li>
|
||||
<li><code>std::map</code></li>
|
||||
<li><code>std::multimap</code></li>
|
||||
<li><code>std::multiset</code></li>
|
||||
<li><code>std::set</code></li>
|
||||
<li><code>std::vector</code></li>
|
||||
<li><code>std::unordered_map</code></li>
|
||||
<li><code>std::unordered_multimap</code></li>
|
||||
<li><code>std::unordered_set</code></li>
|
||||
<li><code>std::unordered_multiset</code></li>
|
||||
</ul>
|
||||
|
||||
<p>N.B. although there are precondition checks for some string operations,
|
||||
e.g. <code>operator[]</code>,
|
||||
they will not always be run when using the <code>char</code> and
|
||||
<code>wchar_t</code> specialisations (<code>std::string</code> and
|
||||
<code>std::wstring</code>). This is because libstdc++ uses GCC's
|
||||
<code>extern template</code> extension to provide explicit instantiations
|
||||
of <code>std::string</code> and <code>std::wstring</code>, and those
|
||||
explicit instantiations don't include the debug-mode checks. If the
|
||||
containing functions are inlined then the checks will run, so compiling
|
||||
with <code>-O1</code> might be enough to enable them. Alternatively
|
||||
<code>-D_GLIBCXX_EXTERN_TEMPLATE=0</code> will suppress the declarations
|
||||
of the explicit instantiations and cause the functions to be instantiated
|
||||
with the debug-mode checks included, but this is unsupported and not
|
||||
guaranteed to work. For full debug-mode support you can use the
|
||||
<code>__gnu_debug::basic_string</code> debugging container directly,
|
||||
which always works correctly.
|
||||
</p>
|
||||
|
||||
<h3 class="left"><a name="mem">Tips for memory leak hunting</a></h3>
|
||||
|
||||
<p>There are various third party memory tracing and debug utilities
|
||||
that can be used to provide detailed memory allocation information
|
||||
about C++ code. An exhaustive list of tools is not going to be
|
||||
attempted, but includes <code>mtrace</code>, <code>valgrind</code>,
|
||||
<code>mudflap</code>, and the non-free commercial product
|
||||
<code>purify</code>. In addition, <code>libcwd</code> has a
|
||||
replacement for the global new and delete operators that can track
|
||||
memory allocation and deallocation and provide useful memory
|
||||
statistics.
|
||||
</p>
|
||||
|
||||
<p>Regardless of the memory debugging tool being used, there is one
|
||||
thing of great importance to keep in mind when debugging C++ code
|
||||
that uses <code>new</code> and <code>delete</code>:
|
||||
there are different kinds of allocation schemes that can be used by
|
||||
<code> std::allocator </code>. For implementation details, see the
|
||||
<a href="ext/mt_allocator.html">mt allocator</a> documentation and
|
||||
look specifically for <code>GLIBCXX_FORCE_NEW</code>.
|
||||
</p>
|
||||
|
||||
<p>In a nutshell, the default allocator used by <code>
|
||||
std::allocator</code> is a high-performance pool allocator, and can
|
||||
give the mistaken impression that in a suspect executable, memory
|
||||
is being leaked, when in reality the memory "leak" is a pool being
|
||||
used by the library's allocator and is reclaimed after program
|
||||
termination.
|
||||
</p>
|
||||
|
||||
<p>For valgrind, there are some specific items to keep in mind. First
|
||||
of all, use a version of valgrind that will work with current GNU
|
||||
C++ tools: the first that can do this is valgrind 1.0.4, but later
|
||||
versions should work at least as well. Second of all, use a
|
||||
completely unoptimized build to avoid confusing valgrind. Third,
|
||||
use GLIBCXX_FORCE_NEW to keep extraneous pool allocation noise from
|
||||
cluttering debug information.
|
||||
</p>
|
||||
|
||||
<p>Fourth, it may be necessary to force deallocation in other
|
||||
libraries as well, namely the "C" library. On linux, this can be
|
||||
accomplished with the appropriate use of the
|
||||
<code>__cxa_atexit</code> or <code>atexit</code> functions.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
#include <cstdlib>
|
||||
|
||||
extern "C" void __libc_freeres(void);
|
||||
|
||||
void do_something() { }
|
||||
|
||||
int main()
|
||||
{
|
||||
atexit(__libc_freeres);
|
||||
do_something();
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
||||
<p>or, using <code>__cxa_atexit</code>:</p>
|
||||
|
||||
<pre>
|
||||
extern "C" void __libc_freeres(void);
|
||||
extern "C" int __cxa_atexit(void (*func) (void *), void *arg, void *d);
|
||||
|
||||
void do_something() { }
|
||||
|
||||
int main()
|
||||
{
|
||||
extern void* __dso_handle __attribute__ ((__weak__));
|
||||
__cxa_atexit((void (*) (void *)) __libc_freeres, NULL,
|
||||
&__dso_handle ? __dso_handle : NULL);
|
||||
do_test();
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>Suggested valgrind flags, given the suggestions above about setting
|
||||
up the runtime environment, library, and test file, might be:
|
||||
</p>
|
||||
<pre>
|
||||
valgrind -v --num-callers=20 --leak-check=yes --leak-resolution=high --show-reachable=yes a.out
|
||||
</pre>
|
||||
|
||||
|
||||
<h3 class="left"><a name="gdb">Some gdb strategies</a></h3>
|
||||
<p>Many options are available for gdb itself: please see <a
|
||||
href="http://sources.redhat.com/gdb/current/onlinedocs/gdb_13.html#SEC109">
|
||||
"GDB features for C++" </a> in the gdb documentation. Also
|
||||
recommended: the other parts of this manual.
|
||||
</p>
|
||||
|
||||
<p>These settings can either be switched on in at the gdb command
|
||||
line, or put into a .gdbint file to establish default debugging
|
||||
characteristics, like so:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
set print pretty on
|
||||
set print object on
|
||||
set print static-members on
|
||||
set print vtbl on
|
||||
set print demangle on
|
||||
set demangle-style gnu-v3
|
||||
</pre>
|
||||
|
||||
|
||||
<h3 class="left"><a name="verbterm">Tracking uncaught exceptions</a></h3>
|
||||
<p>The <a href="18_support/howto.html#4">verbose termination handler</a>
|
||||
gives information about uncaught exceptions which are killing the
|
||||
program. It is described in the linked-to page.
|
||||
</p>
|
||||
|
||||
|
||||
<p>Return <a href="#top">to the top of the page</a> or
|
||||
<a href="http://gcc.gnu.org/libstdc++/">to the libstdc++ homepage</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<hr />
|
||||
<p class="fineprint"><em>
|
||||
See <a href="17_intro/license.html">license.html</a> for copying conditions.
|
||||
Comments and suggestions are welcome, and may be sent to
|
||||
<a href="mailto:libstdc++@gcc.gnu.org">the libstdc++ mailing list</a>.
|
||||
</em></p>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,361 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta name="KEYWORDS"
|
||||
content="libstdc++, homepage, home, C++, library, c++, std, g++, STL" />
|
||||
<title>The GNU C++ Library</title>
|
||||
<link rel="StyleSheet" href="lib3styles.css" type="text/css" />
|
||||
<link rel="Copyright" href="17_intro/license.html" type="text/html" />
|
||||
<link rel="Help" href="faq/index.html" type="text/html" title="F.A.Q." />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1>The GNU C++ Library</h1>
|
||||
|
||||
|
||||
<h2><a name="3">Table of Contents</a></h2>
|
||||
|
||||
<p>
|
||||
The GNU Standard C++ Library is an ongoing <a
|
||||
href="http://gcc.gnu.org/libstdc++">project</a> to implement the ISO
|
||||
14882 Standard C++ library as described in chapters 17 through 27 and
|
||||
annex D, extensions as described by TR1, and future C++ library
|
||||
standards still in progress. For those who want to see exactly how far
|
||||
the project has come, or just want the latest bleeding-edge code, the
|
||||
up-to-date source is always publicly available over anonymous SVN,
|
||||
and can be browsed over the <a
|
||||
href="http://gcc.gnu.org/svn.html">web</a>.
|
||||
</p>
|
||||
|
||||
<p>Stable versions of libstdc++ are included with releases of
|
||||
<a href="http://gcc.gnu.org/releases.html">the GCC compilers</a>.
|
||||
</p>
|
||||
<ul>
|
||||
<li>Introduction
|
||||
<ul>
|
||||
|
||||
<li> Status
|
||||
<ul>
|
||||
<li>Implementation Status
|
||||
<ul>
|
||||
<li><a href="17_intro/c++1998_status.html">C++1998</a>,
|
||||
including <a href="17_intro/howto.html#5">implementation-defined behavior</a> and <a href="ext/howto.html#5">LWG issues</a> </li>
|
||||
<li><a href="17_intro/tr1_status.html">C++TR1</a></li>
|
||||
<li><a href="17_intro/c++0x_status.html">C++0x</a></li>
|
||||
<li>Extensions</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="17_intro/license.html">License</a></li>
|
||||
<li><a href="http://gcc.gnu.org/bugzilla/buglist.cgi?cmdtype=runnamed&namedcmd=libstdc%2B%2B">Known Bugs</a></li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
|
||||
|
||||
<li> Configuring, Building, Testing, Installing
|
||||
<ul>
|
||||
<li><a href="install.html">Getting started: configure, build, install</a>
|
||||
</li>
|
||||
<li><a href="configopts.html">Configure options</a></li>
|
||||
<li><a href="test.html">Testing details</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li> Using the Library
|
||||
<ul>
|
||||
<li>Header Files
|
||||
<ul>
|
||||
<li><a href="17_intro/howto.html#2.0">Available headers</a></li>
|
||||
<li><a href="17_intro/howto.html#2.1">Mixing headers</a></li>
|
||||
<li><a href="17_intro/howto.html#2.2">The C Headers and <code>namespace std</code></a></li>
|
||||
<li><a href="17_intro/howto.html#2.3">Precompiled Headers</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>Namespaces
|
||||
<ul>
|
||||
<li><a href="17_intro/howto.html#3.0">Available namespaces</a></li>
|
||||
<li><a href="17_intro/howto.html#3.1">Namespace <code>std::</code></a></li>
|
||||
<li><a href="17_intro/howto.html#3.2">Using namespace composition</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="17_intro/howto.html#6">Macros</a></li>
|
||||
<li>Command line options</li>
|
||||
|
||||
<li>Concurrency
|
||||
<ul>
|
||||
<li><a href="faq/index.html#5_6">Is it thread safe?</a></li>
|
||||
<li><a href="17_intro/howto.html#7">Thread safety history and evolution</a></li>
|
||||
<li><a href="23_containers/howto.html#3">Containers</a></li>
|
||||
<li><a href="27_io/howto.html#9">IO</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>Exception safety</li>
|
||||
|
||||
<li><a href="debug.html">Debugging support</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>Support
|
||||
<ul>
|
||||
<li><a href="18_support/howto.html#1">Types</a></li>
|
||||
<li><a href="18_support/howto.html#2">Implementation properties of builtin types</a></li>
|
||||
<li><a href="18_support/howto.html#3">Start and Termination</a></li>
|
||||
<li><a href="18_support/howto.html#4">Verbose <code>terminate</code></a></li>
|
||||
<li><a href="18_support/howto.html#5">Dynamic memory management</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>Diagnostics
|
||||
<ul>
|
||||
<li>Exceptions
|
||||
|
||||
<ul>
|
||||
<li>Exception class hierarchy</li>
|
||||
<li><a href="19_diagnostics/howto.html#1">Adding data to exceptions</a></li>
|
||||
<li>Cancellation</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li><a href="19_diagnostics/howto.html#3">Concept checking</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>General Utilities
|
||||
<ul>
|
||||
<li><a href="20_util/howto.html#3">Functors</a></li>
|
||||
<li><a href="20_util/howto.html#4">Pairs</a></li>
|
||||
|
||||
<li>Memory
|
||||
<ul>
|
||||
<li><a href="20_util/allocator.html">allocator</a></li>
|
||||
<li>auto_ptr
|
||||
<ul>
|
||||
<li><a href="20_util/howto.html#1"><code>auto_ptr</code> is not omnipotent</a></li>
|
||||
<li><a href="20_util/howto.html#2"><code>auto_ptr</code> inside container classes</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li>shared_ptr
|
||||
<ul>
|
||||
<li><a href="20_util/shared_ptr.html">Notes on the <code>shared_ptr</code>
|
||||
implementation</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>Strings
|
||||
<ul>
|
||||
<li><a href="21_strings/howto.html#2">A case-insensitive string class</a></li>
|
||||
<li><a href="21_strings/howto.html#3">Breaking a C++ string into tokens</a></li>
|
||||
<li><a href="21_strings/howto.html#4">Simple transformations</a></li>
|
||||
<li><a href="21_strings/howto.html#5">Making strings of arbitrary character types</a></li>
|
||||
<li><a href="21_strings/howto.html#6">Shrink-to-fit strings</a></li>
|
||||
<li><a href="21_strings/howto.html#1">MFC's CString</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>Localization
|
||||
<ul>
|
||||
<li><a href="22_locale/howto.html#1">class locale</a></li>
|
||||
<li><a href="22_locale/howto.html#2">class codecvt</a></li>
|
||||
<li><a href="22_locale/howto.html#3">class ctype</a></li>
|
||||
<li><a href="22_locale/howto.html#7">Correct Transformations</a></li>
|
||||
<li><a href="22_locale/howto.html#4">class messages</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>Containers
|
||||
<ul>
|
||||
<li><a href="23_containers/howto.html#1">Making code unaware of the container/array difference</a></li>
|
||||
<li><a href="23_containers/howto.html#4">"Hinting" during insertion</a></li>
|
||||
<li><a href="23_containers/howto.html#6"><code>std::list::size()</code> is O(n)!</a></li>
|
||||
<li><a href="23_containers/howto.html#7">Space overhead management for vectors</a></li>
|
||||
<li><a href="23_containers/howto.html#2">Variable-sized bitmasks</a></li>
|
||||
<li><a href="23_containers/howto.html#5">Bitmasks and string arguments</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>Iterators
|
||||
<ul>
|
||||
<li><a href="24_iterators/howto.html#1">They ain't pointers!</a></li>
|
||||
<li><a href="24_iterators/howto.html#2">It ends <em>where?</em></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>Algorithms
|
||||
<ul>
|
||||
<li><a href="25_algorithms/howto.html#1">Prerequisites</a></li>
|
||||
<li><a href="25_algorithms/howto.html#2">Specializations for <code>swap</code></a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>Numerics
|
||||
<ul>
|
||||
<li><a href="26_numerics/howto.html#1">Complex Number Processing</a></li>
|
||||
<li><a href="26_numerics/howto.html#2">Array Processing</a></li>
|
||||
<li><a href="26_numerics/howto.html#3">Numerical Functions</a></li>
|
||||
<li><a href="26_numerics/howto.html#4">C99</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>Input/Output
|
||||
<ul>
|
||||
<li><a href="27_io/howto.html#1">Copying a file</a></li>
|
||||
<li><a href="27_io/howto.html#2">The buffering is screwing up my program!</a></li>
|
||||
<li><a href="27_io/howto.html#3">Binary I/O</a></li>
|
||||
<li><a href="27_io/howto.html#5">What is this <sstream>/stringstreams thing?</a></li>
|
||||
<li><a href="27_io/howto.html#6">Deriving a stream buffer</a></li>
|
||||
<li><a href="27_io/howto.html#7">More on binary I/O</a></li>
|
||||
<li><a href="27_io/howto.html#8">Pathetic performance? Ditch C.</a></li>
|
||||
<li><a href="27_io/howto.html#9">Threads and I/O</a></li>
|
||||
<li><a href="27_io/howto.html#10">Which header?</a></li>
|
||||
<li><a href="27_io/howto.html#11">Using FILE*s and file descriptors with IOStreams</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>Extensions
|
||||
<ul>
|
||||
<li><a href="ext/howto.html#4">Compile-time checks</a></li>
|
||||
<li><a href="ext/debug_mode.html">Debug mode</a></li>
|
||||
<li><a href="ext/parallel_mode.html">Parallel mode</a></li>
|
||||
<li> Allocators
|
||||
<ul>
|
||||
<li><a href="ext/mt_allocator.html"><code>__mt_alloc</code> </a></li>
|
||||
<li><a href="ext/ballocator_doc.html">Bitmap Allocator</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li> Containers
|
||||
<ul>
|
||||
<li><a href="ext/pb_ds/index.html">Policy Based Data Structures</a></li>
|
||||
<li><a href="ext/howto.html#1">Ropes and trees and hashes, oh my!</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li> Algorithms
|
||||
<ul>
|
||||
<li><a href="ext/sgiexts.html">HP/SGI STL Extensions</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li> Input/Output
|
||||
<ul>
|
||||
<li><a href="27_io/howto.html#11">Derived filebuf classes</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="ext/../18_support/howto.html#6">Demangling</a></li>
|
||||
<li><a href="ext/concurrence.html">Concurrency: Threads and Atomics</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>Appendix
|
||||
<ul>
|
||||
|
||||
<li>A. <a name="5">Contributing and Maintenance</a>
|
||||
<ul>
|
||||
<li><a href="17_intro/contribute.html">Contributor checklist</a></li>
|
||||
<li><a href="http://gcc.gnu.org/svnwrite.html">Getting write access
|
||||
(look for "Write after approval")</a></li>
|
||||
<li><a href="17_intro/BADNAMES">Identifier blacklist</a>
|
||||
- names to avoid because of potential collisions</li>
|
||||
<li><a href="17_intro/C++STYLE">Coding style, by example</a></li>
|
||||
|
||||
<li> Comment coding style, a doxygen markup style guide. In the source docs/doxygen directory, see <a href="http://gcc.gnu.org/viewcvs/*checkout*/trunk/libstdc%2B%2B-v3/docs/doxygen/guide.html">guide.html</a>.</li>
|
||||
<li><a href="17_intro/DESIGN">Design Notes</a>
|
||||
- notes on the implementation plan</li>
|
||||
<li><a href="17_intro/configury.html">Editing configure and make files</a></li>
|
||||
<li>Header policy, namespace map, API conventions</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>B. Porting
|
||||
|
||||
<ul>
|
||||
<li><a href="17_intro/porting.html">Porting to new hardware or operating systems.</a></li>
|
||||
<li><a href="17_intro/abi.html">ABI Policy and Guidelines</a></li>
|
||||
<li><a href="17_intro/api.html">API Evolution and Deprecation History</a></li>
|
||||
<li><a href="17_intro/backwards_compatibility.html">Backwards Compatibility</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
<li>C. <a href="http://www.gnu.org/software/libc/manual/html_node/Free-Manuals.html#Free-Manuals">Free Software Needs Free Documentation </a></li>
|
||||
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<!-- endlist -->
|
||||
|
||||
|
||||
<hr />
|
||||
<br />
|
||||
<h2><a name="4">Source-Level Documentation</a></h2>
|
||||
<p>The library sources have been specially formatted so that with the
|
||||
proper invocation of another tool (Doxygen), a set of HTML pages
|
||||
are generated from the sources files themselves. The resultant
|
||||
documentation is referred to as Source-Level Documentation, and is
|
||||
useful for examining the signatures of public member functions for
|
||||
the library classes, finding out what is in a particular include
|
||||
file, looking at inheritance diagrams, etc.
|
||||
</p>
|
||||
<p>The source-level documentation for the most recent releases can
|
||||
be viewed online:
|
||||
</p>
|
||||
<ul>
|
||||
<li><a href="libstdc++-html-USERS-3.4/index.html">for the 3.4 release</a></li>
|
||||
<li><a href="libstdc++-html-USERS-4.1/index.html">for the 4.1 release</a></li>
|
||||
<li><a href="libstdc++-html-USERS-4.2/index.html">for the 4.2 release</a></li>
|
||||
<li><a href="latest-doxygen/index.html">"the latest collection"</a>
|
||||
(for the main development tree; see the date on the first page)
|
||||
</li>
|
||||
</ul>
|
||||
<p>This generated HTML collection, as above, is also available for download in
|
||||
the libstdc++ snapshots directory at
|
||||
<code><URL:ftp://gcc.gnu.org/pub/gcc/libstdc++/doxygen/></code>.
|
||||
You will almost certainly need to use one of the
|
||||
<a href="http://gcc.gnu.org/mirrors.html">mirror sites</a> to download
|
||||
the tarball. After unpacking, simply load libstdc++-html-*/index.html
|
||||
into a browser.
|
||||
</p>
|
||||
<p>Documentation for older releases is available for download only, not
|
||||
online viewing.
|
||||
</p>
|
||||
<p>In addition, an initial set of man pages are also available in the
|
||||
same place as the HTML collections. Start with C++Intro(3).
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<br />
|
||||
<h2><a name="7" href="faq/index.html">Frequently Asked Questions</a></h2>
|
||||
|
||||
<hr />
|
||||
<br />
|
||||
<p><strong>All of these documents</strong> (in fact, this entire homepage set)
|
||||
are bundled with the library source, under the <code>docs</code>
|
||||
subdirectory, for releases and snapshots. The sole exception is the
|
||||
automatically-generated source documentation, available separately.
|
||||
</p>
|
||||
|
||||
<!-- ####################################################### -->
|
||||
<p>Return <a href="http://gcc.gnu.org/libstdc++/">to the libstdc++ homepage</a>.</p>
|
||||
|
||||
|
||||
<hr />
|
||||
<p class="fineprint"><em>
|
||||
See <a href="17_intro/license.html">license.html</a> for copying conditions.
|
||||
Comments and suggestions are welcome, and may be sent to
|
||||
<a href="mailto:libstdc++@gcc.gnu.org">the libstdc++ mailing list</a>.
|
||||
</em></p>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,426 +0,0 @@
|
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta content="text/html; charset=ISO-8859-1"
|
||||
http-equiv="content-type">
|
||||
<title>Bitmap Allocator</title>
|
||||
<meta content="Dhruv Matani" name="author">
|
||||
<meta content="Bitmap Allocator" name="description">
|
||||
</head>
|
||||
<body>
|
||||
<h1 style="text-align: center;">Bitmap Allocator</h1>
|
||||
<em><br>
|
||||
<small><small>The latest version of this document is always available
|
||||
at <a
|
||||
href="http://gcc.gnu.org/onlinedocs/libstdc++/ext/ballocator_doc.html">
|
||||
http://gcc.gnu.org/onlinedocs/libstdc++/ext/ballocator_doc.html</a>.</small></small></em><br>
|
||||
<br>
|
||||
<em> To the <a href="http://gcc.gnu.org/libstdc++/">libstdc++
|
||||
homepage</a>.</em><br>
|
||||
<br>
|
||||
<hr style="width: 100%; height: 2px;"><br>
|
||||
As this name suggests, this allocator uses a bit-map to keep track of
|
||||
the used and unused memory locations for it's book-keeping purposes.<br>
|
||||
<br>
|
||||
This allocator will make use of 1 single bit to keep track of whether
|
||||
it has been allocated or not. A bit 1 indicates free, while 0 indicates
|
||||
allocated. This has been done so that you can easily check a collection
|
||||
of bits for a free block. This kind of Bitmapped strategy works best
|
||||
for single object allocations, and with the STL type parameterized
|
||||
allocators, we do not need to choose any size for the block which will
|
||||
be represented by a single bit. This will be the size of the parameter
|
||||
around which the allocator has been parameterized. Thus, close to
|
||||
optimal performance will result. Hence, this should be used for node
|
||||
based containers which call the allocate function with an argument of 1.<br>
|
||||
<br>
|
||||
The bitmapped allocator's internal pool is exponentially growing.
|
||||
Meaning that internally, the blocks acquired from the Free List Store
|
||||
will double every time the bitmapped allocator runs out of memory.<br>
|
||||
<br>
|
||||
<hr style="width: 100%; height: 2px;"><br>
|
||||
The macro __GTHREADS decides whether to use Mutex Protection around
|
||||
every allocation/deallocation. The state of the macro is picked up
|
||||
automatically from the gthr abstraction layer.<br>
|
||||
<br>
|
||||
<hr style="width: 100%; height: 2px;">
|
||||
<h3 style="text-align: center;">What is the Free List Store?</h3>
|
||||
<br>
|
||||
The Free List Store (referred to as FLS for the remaining part of this
|
||||
document) is the Global memory pool that is shared by all instances of
|
||||
the bitmapped allocator instantiated for any type. This maintains a
|
||||
sorted order of all free memory blocks given back to it by the
|
||||
bitmapped allocator, and is also responsible for giving memory to the
|
||||
bitmapped allocator when it asks for more.<br>
|
||||
<br>
|
||||
Internally, there is a Free List threshold which indicates the Maximum
|
||||
number of free lists that the FLS can hold internally (cache).
|
||||
Currently, this value is set at 64. So, if there are more than 64 free
|
||||
lists coming in, then some of them will be given back to the OS using
|
||||
operator delete so that at any given time the Free List's size does not
|
||||
exceed 64 entries. This is done because a Binary Search is used to
|
||||
locate an entry in a free list when a request for memory comes along.
|
||||
Thus, the run-time complexity of the search would go up given an
|
||||
increasing size, for 64 entries however, lg(64) == 6 comparisons are
|
||||
enough to locate the correct free list if it exists.<br>
|
||||
<br>
|
||||
Suppose the free list size has reached it's threshold, then the largest
|
||||
block from among those in the list and the new block will be selected
|
||||
and given back to the OS. This is done because it reduces external
|
||||
fragmentation, and allows the OS to use the larger blocks later in an
|
||||
orderly fashion, possibly merging them later. Also, on some systems,
|
||||
large blocks are obtained via calls to mmap, so giving them back to
|
||||
free system resources becomes most important.<br>
|
||||
<br>
|
||||
The function _S_should_i_give decides the policy that determines
|
||||
whether the current block of memory should be given to the allocator
|
||||
for the request that it has made. That's because we may not always have
|
||||
exact fits for the memory size that the allocator requests. We do this
|
||||
mainly to prevent external fragmentation at the cost of a little
|
||||
internal fragmentation. Now, the value of this internal fragmentation
|
||||
has to be decided by this function. I can see 3 possibilities right
|
||||
now. Please add more as and when you find better strategies.<br>
|
||||
<br>
|
||||
<ol>
|
||||
<li>Equal size check. Return true only when the 2 blocks are of equal
|
||||
size.</li>
|
||||
<li>Difference Threshold: Return true only when the _block_size is
|
||||
greater than or equal to the _required_size, and if the _BS is > _RS
|
||||
by a difference of less than some THRESHOLD value, then return true,
|
||||
else return false. </li>
|
||||
<li>Percentage Threshold. Return true only when the _block_size is
|
||||
greater than or equal to the _required_size, and if the _BS is > _RS
|
||||
by a percentage of less than some THRESHOLD value, then return true,
|
||||
else return false.</li>
|
||||
</ol>
|
||||
<br>
|
||||
Currently, (3) is being used with a value of 36% Maximum wastage per
|
||||
Super Block.<br>
|
||||
<br>
|
||||
<hr style="width: 100%; height: 2px;"><span style="font-weight: bold;">1)
|
||||
What is a super block? Why is it needed?</span><br>
|
||||
<br>
|
||||
A super block is the block of memory acquired from the FLS from which
|
||||
the bitmap allocator carves out memory for single objects and satisfies
|
||||
the user's requests. These super blocks come in sizes that are powers
|
||||
of 2 and multiples of 32 (_Bits_Per_Block). Yes both at the same time!
|
||||
That's because the next super block acquired will be 2 times the
|
||||
previous one, and also all super blocks have to be multiples of the
|
||||
_Bits_Per_Block value. <br>
|
||||
<br>
|
||||
<span style="font-weight: bold;">2) How does it interact with the free
|
||||
list store?</span><br>
|
||||
<br>
|
||||
The super block is contained in the FLS, and the FLS is responsible for
|
||||
getting / returning Super Bocks to and from the OS using operator new
|
||||
as defined by the C++ standard.<br>
|
||||
<br>
|
||||
<hr style="width: 100%; height: 2px;">
|
||||
<h3 style="text-align: center;">How does the allocate function Work?</h3>
|
||||
<br>
|
||||
The allocate function is specialized for single object allocation ONLY.
|
||||
Thus, ONLY if n == 1, will the bitmap_allocator's specialized algorithm
|
||||
be used. Otherwise, the request is satisfied directly by calling
|
||||
operator new.<br>
|
||||
<br>
|
||||
Suppose n == 1, then the allocator does the following:<br>
|
||||
<br>
|
||||
<ol>
|
||||
<li>Checks to see whether a free block exists somewhere in a
|
||||
region of memory close to the last satisfied request. If so, then that
|
||||
block is marked as allocated in the bit map and given to the user. If
|
||||
not, then (2) is executed.</li>
|
||||
<li>Is there a free block anywhere after the current block right up to
|
||||
the end of the memory that we have? If so, that block is found, and the
|
||||
same procedure is applied as above, and returned to the user. If not,
|
||||
then (3) is executed.</li>
|
||||
<li>Is there any block in whatever region of memory that we own free?
|
||||
This is done by checking <br>
|
||||
<div style="margin-left: 40px;">
|
||||
<ul>
|
||||
<li>The use count for each super block, and if that fails then </li>
|
||||
<li>The individual bit-maps for each super block. </li>
|
||||
</ul>
|
||||
</div>
|
||||
Note: Here we are never touching any of the memory that the user will
|
||||
be given, and we are confining all memory accesses to a small region of
|
||||
memory! This helps reduce cache misses. If this succeeds then we apply
|
||||
the same procedure on that bit-map as (1), and return that block of
|
||||
memory to the user. However, if this process fails, then we resort to
|
||||
(4).</li>
|
||||
<li>This process involves Refilling the internal exponentially
|
||||
growing memory pool. The said effect is achieved by calling
|
||||
_S_refill_pool which does the following: <br>
|
||||
<div style="margin-left: 40px;">
|
||||
<ul>
|
||||
<li>Gets more memory from the Global Free List of the Required
|
||||
size. </li>
|
||||
<li>Adjusts the size for the next call to itself. </li>
|
||||
<li>Writes the appropriate headers in the bit-maps.</li>
|
||||
<li>Sets the use count for that super-block just allocated to 0
|
||||
(zero). </li>
|
||||
<li>All of the above accounts to maintaining the basic invariant
|
||||
for the allocator. If the invariant is maintained, we are sure that all
|
||||
is well. Now, the same process is applied on the newly acquired free
|
||||
blocks, which are dispatched accordingly.</li>
|
||||
</ul>
|
||||
</div>
|
||||
</li>
|
||||
</ol>
|
||||
<br>
|
||||
Thus, you can clearly see that the allocate function is nothing but a
|
||||
combination of the next-fit and first-fit algorithm optimized ONLY for
|
||||
single object allocations.<br>
|
||||
<br>
|
||||
<br>
|
||||
<hr style="width: 100%; height: 2px;">
|
||||
<h3 style="text-align: center;">How does the deallocate function work?</h3>
|
||||
<br>
|
||||
The deallocate function again is specialized for single objects ONLY.
|
||||
For all n belonging to > 1, the operator delete is called without
|
||||
further ado, and the deallocate function returns.<br>
|
||||
<br>
|
||||
However for n == 1, a series of steps are performed:<br>
|
||||
<br>
|
||||
<ol>
|
||||
<li>We first need to locate that super-block which holds the memory
|
||||
location given to us by the user. For that purpose, we maintain a
|
||||
static variable _S_last_dealloc_index, which holds the index into the
|
||||
vector of block pairs which indicates the index of the last super-block
|
||||
from which memory was freed. We use this strategy in the hope that the
|
||||
user will deallocate memory in a region close to what he/she
|
||||
deallocated the last time around. If the check for belongs_to succeeds,
|
||||
then we determine the bit-map for the given pointer, and locate the
|
||||
index into that bit-map, and mark that bit as free by setting it.</li>
|
||||
<li>If the _S_last_dealloc_index does not point to the memory block
|
||||
that we're looking for, then we do a linear search on the block stored
|
||||
in the vector of Block Pairs. This vector in code is called
|
||||
_S_mem_blocks. When the corresponding super-block is found, we apply
|
||||
the same procedure as we did for (1) to mark the block as free in the
|
||||
bit-map.</li>
|
||||
</ol>
|
||||
<br>
|
||||
Now, whenever a block is freed, the use count of that particular super
|
||||
block goes down by 1. When this use count hits 0, we remove that super
|
||||
block from the list of all valid super blocks stored in the vector.
|
||||
While doing this, we also make sure that the basic invariant is
|
||||
maintained by making sure that _S_last_request and
|
||||
_S_last_dealloc_index point to valid locations within the vector.<br>
|
||||
<br>
|
||||
<hr style="width: 100%; height: 2px;"><br>
|
||||
<h3 style="text-align: center;">Data Layout for a Super Block:</h3>
|
||||
<br>
|
||||
Each Super Block will be of some size that is a multiple of the number
|
||||
of Bits Per Block. Typically, this value is chosen as Bits_Per_Byte x
|
||||
sizeof(size_t). On an x86 system, this gives the figure 8 x
|
||||
4 = 32. Thus, each Super Block will be of size 32 x Some_Value. This
|
||||
Some_Value is sizeof(value_type). For now, let it be called 'K'. Thus,
|
||||
finally, Super Block size is 32 x K bytes.<br>
|
||||
<br>
|
||||
This value of 32 has been chosen because each size_t has 32-bits
|
||||
and Maximum use of these can be made with such a figure.<br>
|
||||
<br>
|
||||
Consider a block of size 64 ints. In memory, it would look like this:
|
||||
(assume a 32-bit system where, size_t is a 32-bit entity).<br>
|
||||
<br>
|
||||
<table cellpadding="0" cellspacing="0" border="1"
|
||||
style="text-align: left; width: 763px; height: 21px;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="vertical-align: top; text-align: center;">268<br>
|
||||
</td>
|
||||
<td style="vertical-align: top; text-align: center;">0<br>
|
||||
</td>
|
||||
<td style="vertical-align: top; text-align: center;">4294967295<br>
|
||||
</td>
|
||||
<td style="vertical-align: top; text-align: center;">4294967295<br>
|
||||
</td>
|
||||
<td style="vertical-align: top; text-align: center;">Data ->
|
||||
Space for 64 ints<br>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
<br>
|
||||
The first Column(268) represents the size of the Block in bytes as seen
|
||||
by
|
||||
the Bitmap Allocator. Internally, a global free list is used to keep
|
||||
track of the free blocks used and given back by the bitmap allocator.
|
||||
It is this Free List Store that is responsible for writing and managing
|
||||
this information. Actually the number of bytes allocated in this case
|
||||
would be: 4 + 4 + (4x2) + (64x4) = 272 bytes, but the first 4 bytes are
|
||||
an
|
||||
addition by the Free List Store, so the Bitmap Allocator sees only 268
|
||||
bytes. These first 4 bytes about which the bitmapped allocator is not
|
||||
aware hold the value 268.<br>
|
||||
<br>
|
||||
<span style="font-weight: bold;">What do the remaining values represent?</span><br>
|
||||
<br>
|
||||
The 2nd 4 in the expression is the sizeof(size_t) because the
|
||||
Bitmapped Allocator maintains a used count for each Super Block, which
|
||||
is initially set to 0 (as indicated in the diagram). This is
|
||||
incremented every time a block is removed from this super block
|
||||
(allocated), and decremented whenever it is given back. So, when the
|
||||
used count falls to 0, the whole super block will be given back to the
|
||||
Free List Store.<br>
|
||||
<br>
|
||||
The value 4294967295 represents the integer corresponding to the bit
|
||||
representation of all bits set: 11111111111111111111111111111111.<br>
|
||||
<br>
|
||||
The 3rd 4x2 is size of the bitmap itself, which is the size of 32-bits
|
||||
x 2,
|
||||
which is 8-bytes, or 2 x sizeof(size_t).<br>
|
||||
<br>
|
||||
<hr style="width: 100%; height: 2px;"><br>
|
||||
Another issue would be whether to keep the all bitmaps in a separate
|
||||
area in memory, or to keep them near the actual blocks that will be
|
||||
given out or allocated for the client. After some testing, I've decided
|
||||
to keep these bitmaps close to the actual blocks. This will help in 2
|
||||
ways. <br>
|
||||
<br>
|
||||
<ol>
|
||||
<li>Constant time access for the bitmap themselves, since no kind of
|
||||
look up will be needed to find the correct bitmap list or it's
|
||||
equivalent.</li>
|
||||
<li>And also this would preserve the cache as far as possible.</li>
|
||||
</ol>
|
||||
<br>
|
||||
So in effect, this kind of an allocator might prove beneficial from a
|
||||
purely cache point of view. But this allocator has been made to try and
|
||||
roll out the defects of the node_allocator, wherein the nodes get
|
||||
skewed about in memory, if they are not returned in the exact reverse
|
||||
order or in the same order in which they were allocated. Also, the
|
||||
new_allocator's book keeping overhead is too much for small objects and
|
||||
single object allocations, though it preserves the locality of blocks
|
||||
very well when they are returned back to the allocator.<br>
|
||||
<br>
|
||||
<hr style="width: 100%; height: 2px;"><br>
|
||||
Expected overhead per block would be 1 bit in memory. Also, once the
|
||||
address of the free list has been found, the cost for
|
||||
allocation/deallocation would be negligible, and is supposed to be
|
||||
constant time. For these very reasons, it is very important to minimize
|
||||
the linear time costs, which include finding a free list with a free
|
||||
block while allocating, and finding the corresponding free list for a
|
||||
block while deallocating. Therefore, I have decided that the growth of
|
||||
the internal pool for this allocator will be exponential as compared to
|
||||
linear for node_allocator. There, linear time works well, because we
|
||||
are mainly concerned with speed of allocation/deallocation and memory
|
||||
consumption, whereas here, the allocation/deallocation part does have
|
||||
some linear/logarithmic complexity components in it. Thus, to try and
|
||||
minimize them would be a good thing to do at the cost of a little bit
|
||||
of memory.<br>
|
||||
<br>
|
||||
Another thing to be noted is the pool size will double every time
|
||||
the internal pool gets exhausted, and all the free blocks have been
|
||||
given away. The initial size of the pool would be sizeof(size_t) x 8
|
||||
which is the number of bits in an integer, which can fit exactly
|
||||
in a CPU register. Hence, the term given is exponential growth of the
|
||||
internal pool.<br>
|
||||
<br>
|
||||
<hr style="width: 100%; height: 2px;">After reading all this, you may
|
||||
still have a few questions about the internal working of this
|
||||
allocator, like my friend had!<br>
|
||||
<br>
|
||||
Well here are the exact questions that he posed:<br>
|
||||
<br>
|
||||
<span style="font-weight: bold;">Q1) The "Data Layout" section is
|
||||
cryptic. I have no idea of what you are trying to say. Layout of what?
|
||||
The free-list? Each bitmap? The Super Block?</span><br>
|
||||
<br>
|
||||
<div style="margin-left: 40px;"> The layout of a Super Block of a given
|
||||
size. In the example, a super block of size 32 x 1 is taken. The
|
||||
general formula for calculating the size of a super block is
|
||||
32 x sizeof(value_type) x 2^n, where n ranges from 0 to 32 for 32-bit
|
||||
systems.<br>
|
||||
</div>
|
||||
<br>
|
||||
<span style="font-weight: bold;">Q2) And since I just mentioned the
|
||||
term `each bitmap', what in the world is meant by it? What does each
|
||||
bitmap manage? How does it relate to the super block? Is the Super
|
||||
Block a bitmap as well?</span><br style="font-weight: bold;">
|
||||
<br>
|
||||
<div style="margin-left: 40px;"> Good question! Each bitmap is part of
|
||||
a
|
||||
Super Block which is made up of 3 parts as I have mentioned earlier.
|
||||
Re-iterating, 1. The use count, 2. The bit-map for that Super Block. 3.
|
||||
The actual memory that will be eventually given to the user. Each
|
||||
bitmap is a multiple of 32 in size. If there are 32 x (2^3) blocks of
|
||||
single objects to be given, there will be '32 x (2^3)' bits present.
|
||||
Each
|
||||
32 bits managing the allocated / free status for 32 blocks. Since each
|
||||
size_t contains 32-bits, one size_t can manage up to 32
|
||||
blocks' status. Each bit-map is made up of a number of size_t,
|
||||
whose exact number for a super-block of a given size I have just
|
||||
mentioned.<br>
|
||||
</div>
|
||||
<br>
|
||||
<span style="font-weight: bold;">Q3) How do the allocate and deallocate
|
||||
functions work in regard to bitmaps?</span><br>
|
||||
<br>
|
||||
<div style="margin-left: 40px;"> The allocate and deallocate functions
|
||||
manipulate the bitmaps and have nothing to do with the memory that is
|
||||
given to the user. As I have earlier mentioned, a 1 in the bitmap's bit
|
||||
field indicates free, while a 0 indicates allocated. This lets us check
|
||||
32 bits at a time to check whether there is at lease one free block in
|
||||
those 32 blocks by testing for equality with (0). Now, the allocate
|
||||
function will given a memory block find the corresponding bit in the
|
||||
bitmap, and will reset it (i.e., make it re-set (0)). And when the
|
||||
deallocate function is called, it will again set that bit after
|
||||
locating it to indicate that that particular block corresponding to
|
||||
this bit in the bit-map is not being used by anyone, and may be used to
|
||||
satisfy future requests.<br>
|
||||
<br>
|
||||
e.g.: Consider a bit-map of 64-bits as represented below:<br>
|
||||
1111111111111111111111111111111111111111111111111111111111111111<br>
|
||||
<br>
|
||||
Now, when the first request for allocation of a single object comes
|
||||
along, the first block in address order is returned. And since the
|
||||
bit-maps in the reverse order to that of the address order, the last
|
||||
bit (LSB if the bit-map is considered as a binary word of 64-bits) is
|
||||
re-set to 0.<br>
|
||||
<br>
|
||||
The bit-map now looks like this:<br>
|
||||
1111111111111111111111111111111111111111111111111111111111111110<br>
|
||||
</div>
|
||||
<br>
|
||||
<br>
|
||||
<hr style="width: 100%; height: 2px;"><br>
|
||||
(Tech-Stuff, Please stay out if you are not interested in the selection
|
||||
of certain constants. This has nothing to do with the algorithm per-se,
|
||||
only with some vales that must be chosen correctly to ensure that the
|
||||
allocator performs well in a real word scenario, and maintains a good
|
||||
balance between the memory consumption and the allocation/deallocation
|
||||
speed).<br>
|
||||
<br>
|
||||
The formula for calculating the maximum wastage as a percentage:<br>
|
||||
<br>
|
||||
(32 x k + 1) / (2 x (32 x k + 1 + 32 x c)) x 100.<br>
|
||||
<br>
|
||||
Where,<br>
|
||||
k => The constant overhead per node. eg. for list, it is 8 bytes,
|
||||
and for map it is 12 bytes.<br>
|
||||
c => The size of the base type on which the map/list is
|
||||
instantiated. Thus, suppose the type1 is int and type2 is double,
|
||||
they are related by the relation sizeof(double) == 2*sizeof(int). Thus,
|
||||
all types must have this double size relation for this formula to work
|
||||
properly.<br>
|
||||
<br>
|
||||
Plugging-in: For List: k = 8 and c = 4 (int and double), we get:<br>
|
||||
33.376%<br>
|
||||
<br>
|
||||
For map/multimap: k = 12, and c = 4 (int and double), we get:<br>
|
||||
37.524%<br>
|
||||
<br>
|
||||
Thus, knowing these values, and based on the sizeof(value_type), we may
|
||||
create a function that returns the Max_Wastage_Percentage for us to use.<br>
|
||||
<br>
|
||||
<hr style="width: 100%; height: 2px;"><small><small><em> See <a
|
||||
href="file:///home/dhruv/projects/libstdc++/gcc/libstdc++/docs/html/17_intro/license.html">license.html</a>
|
||||
for copying conditions. Comments and suggestions are welcome, and may
|
||||
be
|
||||
sent to <a href="mailto:libstdc++@gcc.gnu.org">the libstdc++ mailing
|
||||
list</a>.</em><br>
|
||||
</small></small><br>
|
||||
<br>
|
||||
</body>
|
||||
</html>
|
|
@ -1,342 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta name="AUTHOR" content="bkoz@gcc.gnu.org (Benjamin Kosnik)" />
|
||||
<meta name="KEYWORDS" content="C++, libstdc++, MT, thread, pthread, mutex, loc, atomic" />
|
||||
<meta name="DESCRIPTION" content="Concurrency Support" />
|
||||
<meta name="GENERATOR" content="emacs and ten fingers" />
|
||||
<title>Concurrency Support</title>
|
||||
<link rel="StyleSheet" href="lib3styles.css" type="text/css" />
|
||||
<link rel="Start" href="documentation.html" type="text/html"
|
||||
title="GNU C++ Standard Library" />
|
||||
<link rel="Copyright" href="17_intro/license.html" type="text/html" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 class="centered"><a name="top">Concurrency Support</a></h1>
|
||||
|
||||
<p class="fineprint"><em>
|
||||
The latest version of this document is always available at
|
||||
<a href="http://gcc.gnu.org/onlinedocs/libstdc++/17_intro/concurrence.html">
|
||||
http://gcc.gnu.org/onlinedocs/libstdc++/17_intro/concurrence.html</a>.
|
||||
</em></p>
|
||||
|
||||
<p><em>
|
||||
To the <a href="http://gcc.gnu.org/libstdc++/">libstdc++ homepage</a>.
|
||||
</em></p>
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<hr />
|
||||
|
||||
|
||||
<p>The interface for concurrency support is divided into two files:
|
||||
<ext/atomicity.h> which provides support for atomic operations,
|
||||
and <ext/concurrence.h>, which provides mutex and lock objects
|
||||
as well as compile-time data structures for querying thread
|
||||
support.</p>
|
||||
|
||||
<p>It is expected that support for concurrence will evolve into what
|
||||
is specified in the draft C++0x standard.</p>
|
||||
|
||||
<h3 class="left">
|
||||
<a name="atomic_api">Atomics Interface</a>
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
Two functions and one type form the base of atomic support.
|
||||
</p>
|
||||
|
||||
|
||||
<p>The type <code>_Atomic_word</code> is a signed integral type
|
||||
supporting atomic operations.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The two functions functions are:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
_Atomic_word
|
||||
__exchange_and_add_dispatch(volatile _Atomic_word*, int);
|
||||
|
||||
void
|
||||
__atomic_add_dispatch(volatile _Atomic_word*, int);
|
||||
</pre>
|
||||
|
||||
<p>Both of these functions are declared in the header file
|
||||
<ext/atomicity.h>, and are in <code>namespace __gnu_cxx</code>.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<code>
|
||||
__exchange_and_add_dispatch
|
||||
</code>
|
||||
<p>Adds the second argument's value to the first argument. Returns the old value.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<code>
|
||||
__atomic_add_dispatch
|
||||
</code>
|
||||
<p>Adds the second argument's value to the first argument. Has no return value.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
These functions forward to one of several specialized helper
|
||||
functions, depending on the circumstances. For instance,
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<code>
|
||||
__exchange_and_add_dispatch
|
||||
</code>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Calls through to either of:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><code>__exchange_and_add</code>
|
||||
<p>Multi-thread version. Inlined if compiler-generated builtin atomics
|
||||
can be used, otherwise resolved at link time to a non-builtin code
|
||||
sequence.
|
||||
</p>
|
||||
</li>
|
||||
|
||||
<li><code>__exchange_and_add_single</code>
|
||||
<p>Single threaded version. Inlined.</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>However, only <code>__exchange_and_add_dispatch</code>
|
||||
and <code>__atomic_add_dispatch</code> should be used. These functions
|
||||
can be used in a portable manner, regardless of the specific
|
||||
environment. They are carefully designed to provide optimum efficiency
|
||||
and speed, abstracting out atomic accesses when they are not required
|
||||
(even on hosts that support compiler intrinsics for atomic
|
||||
operations.)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In addition, there are two macros
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<code>
|
||||
_GLIBCXX_READ_MEM_BARRIER
|
||||
</code>
|
||||
</p>
|
||||
<p>
|
||||
<code>
|
||||
_GLIBCXX_WRITE_MEM_BARRIER
|
||||
</code>
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Which expand to the appropriate write and read barrier required by the
|
||||
host hardware and operating system.
|
||||
</p>
|
||||
|
||||
<h3 class="left">
|
||||
<a name="pthread_api">Pthread Interface</a>
|
||||
</h3>
|
||||
|
||||
<p>A thin layer above IEEE 1003.1 (ie pthreads) is used to abstract
|
||||
the thread interface for GCC. This layer is called "gthread," and is
|
||||
comprised of one header file that wraps the host's default thread layer with
|
||||
a POSIX-like interface.
|
||||
</p>
|
||||
|
||||
<p> The file <gthr-default.h> points to the deduced wrapper for
|
||||
the current host. In libstdc++ implementation files,
|
||||
<bits/gthr.h> is used to select the proper gthreads file.
|
||||
</p>
|
||||
|
||||
<p>Within libstdc++ sources, all calls to underlying thread functionality
|
||||
use this layer. More detail as to the specific interface can be found in the source <a href="http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/gthr_8h-source.html">documentation</a>.
|
||||
</p>
|
||||
|
||||
<p>By design, the gthread layer is interoperable with the types,
|
||||
functions, and usage found in the usual <pthread.h> file,
|
||||
including <code>pthread_t</code>, <code>pthread_once_t</code>, <code>pthread_create</code>,
|
||||
etc.
|
||||
</p>
|
||||
|
||||
<h3 class="left">
|
||||
<a name="concur_api">Concurrence Interface</a>
|
||||
</h3>
|
||||
|
||||
<p>The file <ext/concurrence.h> contains all the higher-level
|
||||
constructs for playing with threads. In contrast to the atomics layer,
|
||||
the concurrence layer consists largely of types. All types are defined within <code>namespace __gnu_cxx</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
These types can be used in a portable manner, regardless of the
|
||||
specific environment. They are carefully designed to provide optimum
|
||||
efficiency and speed, abstracting out underlying thread calls and
|
||||
accesses when compiling for single-threaded situations (even on hosts
|
||||
that support multiple threads.)
|
||||
</p>
|
||||
|
||||
<p>The enumerated type <code>_Lock_policy</code> details the set of
|
||||
available locking
|
||||
policies: <code>_S_single</code>, <code>_S_mutex</code>,
|
||||
and <code>_S_atomic</code>.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><code>_S_single</code>
|
||||
<p>Indicates single-threaded code that does not need locking.
|
||||
</p>
|
||||
|
||||
</li>
|
||||
<li><code>_S_mutex</code>
|
||||
<p>Indicates multi-threaded code using thread-layer abstractions.
|
||||
</p>
|
||||
</li>
|
||||
<li><code>_S_atomic</code>
|
||||
<p>Indicates multi-threaded code using atomic operations.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>The compile-time constant <code>__default_lock_policy</code> is set
|
||||
to one of the three values above, depending on characteristics of the
|
||||
host environment and the current compilation flags.
|
||||
</p>
|
||||
|
||||
<p>Two more datatypes make up the rest of the
|
||||
interface: <code>__mutex</code>, and <code>__scoped_lock</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
</p>
|
||||
|
||||
<p>The scoped lock idiom is well-discussed within the C++
|
||||
community. This version takes a <code>__mutex</code> reference, and
|
||||
locks it during construction of <code>__scoped_locke</code> and
|
||||
unlocks it during destruction. This is an efficient way of locking
|
||||
critical sections, while retaining exception-safety.
|
||||
</p>
|
||||
|
||||
<p>Typical usage of the last two constructs is demonstrated as follows:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
#include <ext/concurrence.h>
|
||||
|
||||
namespace
|
||||
{
|
||||
__gnu_cxx::__mutex safe_base_mutex;
|
||||
} // anonymous namespace
|
||||
|
||||
namespace other
|
||||
{
|
||||
void
|
||||
foo()
|
||||
{
|
||||
__gnu_cxx::__scoped_lock sentry(safe_base_mutex);
|
||||
for (int i = 0; i < max; ++i)
|
||||
{
|
||||
_Safe_iterator_base* __old = __iter;
|
||||
__iter = __iter-<_M_next;
|
||||
__old-<_M_detach_single();
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>In this sample code, an anonymous namespace is used to keep
|
||||
the <code>__mutex</code> private to the compilation unit,
|
||||
and <code>__scoped_lock</code> is used to guard access to the critical
|
||||
section within the for loop, locking the mutex on creation and freeing
|
||||
the mutex as control moves out of this block.
|
||||
</p>
|
||||
|
||||
<p>Several exception classes are used to keep track of
|
||||
concurrence-related errors. These classes
|
||||
are: <code>__concurrence_lock_error</code>, <code>__concurrence_unlock_error</code>, <code>__concurrence_wait_error</code>,
|
||||
and <code>__concurrence_broadcast_error</code>.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
<h3 class="left">
|
||||
<a name="atomic_impl">Details on builtin atomic support and library fallbacks</a>
|
||||
</h3>
|
||||
|
||||
<p>The functions for atomic operations described above are either
|
||||
implemented via compiler intrinsics (if the underlying host is
|
||||
capable) or by library fallbacks.</p>
|
||||
|
||||
<p>Compiler intrinsics (builtins) are always preferred. However, as
|
||||
the compiler builtins for atomics are not universally implemented,
|
||||
using them directly is problematic, and can result in undefined
|
||||
function calls. (An example of an undefined symbol from the use
|
||||
of <code>__sync_fetch_and_add</code> on an unsupported host is a
|
||||
missing reference to <code>__sync_fetch_and_add_4</code>.)
|
||||
</p>
|
||||
|
||||
<p>In addition, on some hosts the compiler intrinsics are enabled
|
||||
conditionally, via the <code>-march</code> command line flag. This makes
|
||||
usage vary depending on the target hardware and the flags used during
|
||||
compile.
|
||||
</p>
|
||||
|
||||
<p> If builtins are possible, <code>_GLIBCXX_ATOMIC_BUILTINS</code>
|
||||
will be defined.
|
||||
</p>
|
||||
|
||||
|
||||
<p>For the following hosts, intrinsics are enabled by default.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>alpha</li>
|
||||
<li>ia64</li>
|
||||
<li>powerpc</li>
|
||||
<li>s390</li>
|
||||
</ul>
|
||||
|
||||
<p>For others, some form of <code>-march</code> may work. On
|
||||
non-ancient x86 hardware, <code>-march=native</code> usually does the
|
||||
trick.</p>
|
||||
|
||||
<p> For hosts without compiler intrinsics, but with capable
|
||||
hardware, hand-crafted assembly is selected. This is the case for the following hosts:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>cris</li>
|
||||
<li>hppa</li>
|
||||
<li>i386</li>
|
||||
<li>i486</li>
|
||||
<li>m48k</li>
|
||||
<li>mips</li>
|
||||
<li>sparc</li>
|
||||
</ul>
|
||||
|
||||
<p>And for the rest, a simulated atomic lock via pthreads.
|
||||
</p>
|
||||
|
||||
<p> Detailed information about compiler intrinsics for atomic operations can be found in the GCC <a href="http://gcc.gnu.org/onlinedocs/gcc/Atomic-Builtins.html"> documentation</a>.
|
||||
</p>
|
||||
|
||||
<p> More details on the library fallbacks from the porting <a href="http://gcc.gnu.org/onlinedocs/libstdc++/17_intro/porting.html#Thread%20safety">section</a>.
|
||||
</p>
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,578 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta name="AUTHOR" content="gregod@cs.rpi.edu (Doug Gregor)" />
|
||||
<meta name="KEYWORDS" content="C++, GCC, libstdc++, g++, debug" />
|
||||
<meta name="DESCRIPTION" content="Design of the libstdc++ debug mode." />
|
||||
<meta name="GENERATOR" content="vi and eight fingers" />
|
||||
<title>Design of the libstdc++ debug mode</title>
|
||||
<link rel="StyleSheet" href="lib3styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 class="centered"><a name="top">Design of the libstdc++ debug mode</a></h1>
|
||||
|
||||
<p class="fineprint"><em>
|
||||
The latest version of this document is always available at
|
||||
<a href="http://gcc.gnu.org/onlinedocs/libstdc++/debug_mode.html">
|
||||
http://gcc.gnu.org/onlinedocs/libstdc++/debug_mode.html</a>.
|
||||
</em></p>
|
||||
|
||||
<p><em>
|
||||
To the <a href="http://gcc.gnu.org/libstdc++/">libstdc++ homepage</a>.
|
||||
</em></p>
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<hr />
|
||||
<h1>Debug mode design</h1>
|
||||
<p> The libstdc++ debug mode replaces unsafe (but efficient) standard
|
||||
containers and iterators with semantically equivalent safe standard
|
||||
containers and iterators to aid in debugging user programs. The
|
||||
following goals directed the design of the libstdc++ debug mode:</p>
|
||||
|
||||
<ul>
|
||||
|
||||
<li><b>Correctness</b>: the libstdc++ debug mode must not change
|
||||
the semantics of the standard library for all cases specified in
|
||||
the ANSI/ISO C++ standard. The essence of this constraint is that
|
||||
any valid C++ program should behave in the same manner regardless
|
||||
of whether it is compiled with debug mode or release mode. In
|
||||
particular, entities that are defined in namespace std in release
|
||||
mode should remain defined in namespace std in debug mode, so that
|
||||
legal specializations of namespace std entities will remain
|
||||
valid. A program that is not valid C++ (e.g., invokes undefined
|
||||
behavior) is not required to behave similarly, although the debug
|
||||
mode will abort with a diagnostic when it detects undefined
|
||||
behavior.</li>
|
||||
|
||||
<li><b>Performance</b>: the additional of the libstdc++ debug mode
|
||||
must not affect the performance of the library when it is compiled
|
||||
in release mode. Performance of the libstdc++ debug mode is
|
||||
secondary (and, in fact, will be worse than the release
|
||||
mode).</li>
|
||||
|
||||
<li><b>Usability</b>: the libstdc++ debug mode should be easy to
|
||||
use. It should be easily incorporated into the user's development
|
||||
environment (e.g., by requiring only a single new compiler switch)
|
||||
and should produce reasonable diagnostics when it detects a
|
||||
problem with the user program. Usability also involves detection
|
||||
of errors when using the debug mode incorrectly, e.g., by linking
|
||||
a release-compiled object against a debug-compiled object if in
|
||||
fact the resulting program will not run correctly.</li>
|
||||
|
||||
<li><b>Minimize recompilation</b>: While it is expected that
|
||||
users recompile at least part of their program to use debug
|
||||
mode, the amount of recompilation affects the
|
||||
detect-compile-debug turnaround time. This indirectly affects the
|
||||
usefulness of the debug mode, because debugging some applications
|
||||
may require rebuilding a large amount of code, which may not be
|
||||
feasible when the suspect code may be very localized. There are
|
||||
several levels of conformance to this requirement, each with its
|
||||
own usability and implementation characteristics. In general, the
|
||||
higher-numbered conformance levels are more usable (i.e., require
|
||||
less recompilation) but are more complicated to implement than
|
||||
the lower-numbered conformance levels.
|
||||
<ol>
|
||||
<li><b>Full recompilation</b>: The user must recompile his or
|
||||
her entire application and all C++ libraries it depends on,
|
||||
including the C++ standard library that ships with the
|
||||
compiler. This must be done even if only a small part of the
|
||||
program can use debugging features.</li>
|
||||
|
||||
<li><b>Full user recompilation</b>: The user must recompile
|
||||
his or her entire application and all C++ libraries it depends
|
||||
on, but not the C++ standard library itself. This must be done
|
||||
even if only a small part of the program can use debugging
|
||||
features. This can be achieved given a full recompilation
|
||||
system by compiling two versions of the standard library when
|
||||
the compiler is installed and linking against the appropriate
|
||||
one, e.g., a multilibs approach.</li>
|
||||
|
||||
<li><b>Partial recompilation</b>: The user must recompile the
|
||||
parts of his or her application and the C++ libraries it
|
||||
depends on that will use the debugging facilities
|
||||
directly. This means that any code that uses the debuggable
|
||||
standard containers would need to be recompiled, but code
|
||||
that does not use them (but may, for instance, use IOStreams)
|
||||
would not have to be recompiled.</li>
|
||||
|
||||
<li><b>Per-use recompilation</b>: The user must recompile the
|
||||
parts of his or her application and the C++ libraries it
|
||||
depends on where debugging should occur, and any other code
|
||||
that interacts with those containers. This means that a set of
|
||||
translation units that accesses a particular standard
|
||||
container instance may either be compiled in release mode (no
|
||||
checking) or debug mode (full checking), but must all be
|
||||
compiled in the same way; a translation unit that does not see
|
||||
that standard container instance need not be recompiled. This
|
||||
also means that a translation unit <em>A</em> that contains a
|
||||
particular instantiation
|
||||
(say, <code>std::vector<int></code>) compiled in release
|
||||
mode can be linked against a translation unit <em>B</em> that
|
||||
contains the same instantiation compiled in debug mode (a
|
||||
feature not present with partial recompilation). While this
|
||||
behavior is technically a violation of the One Definition
|
||||
Rule, this ability tends to be very important in
|
||||
practice. The libstdc++ debug mode supports this level of
|
||||
recompilation. </li>
|
||||
|
||||
<li><b>Per-unit recompilation</b>: The user must only
|
||||
recompile the translation units where checking should occur,
|
||||
regardless of where debuggable standard containers are
|
||||
used. This has also been dubbed "<code>-g</code> mode",
|
||||
because the <code>-g</code> compiler switch works in this way,
|
||||
emitting debugging information at a per--translation-unit
|
||||
granularity. We believe that this level of recompilation is in
|
||||
fact not possible if we intend to supply safe iterators, leave
|
||||
the program semantics unchanged, and not regress in
|
||||
performance under release mode because we cannot associate
|
||||
extra information with an iterator (to form a safe iterator)
|
||||
without either reserving that space in release mode
|
||||
(performance regression) or allocating extra memory associated
|
||||
with each iterator with <code>new</code> (changes the program
|
||||
semantics).</li>
|
||||
</ol>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="other">Other implementations</a></h2>
|
||||
<p> There are several existing implementations of debug modes for C++
|
||||
standard library implementations, although none of them directly
|
||||
supports debugging for programs using libstdc++. The existing
|
||||
implementations include:</p>
|
||||
<ul>
|
||||
<li><a
|
||||
href="http://www.mathcs.sjsu.edu/faculty/horstman/safestl.html">SafeSTL</a>:
|
||||
SafeSTL was the original debugging version of the Standard Template
|
||||
Library (STL), implemented by Cay S. Horstmann on top of the
|
||||
Hewlett-Packard STL. Though it inspired much work in this area, it
|
||||
has not been kept up-to-date for use with modern compilers or C++
|
||||
standard library implementations.</li>
|
||||
|
||||
<li><a href="http://www.stlport.org/">STLport</a>: STLport is a free
|
||||
implementation of the C++ standard library derived from the <a
|
||||
href="http://www.sgi.com/tech/stl/">SGI implementation</a>, and
|
||||
ported to many other platforms. It includes a debug mode that uses a
|
||||
wrapper model (that in some way inspired the libstdc++ debug mode
|
||||
design), although at the time of this writing the debug mode is
|
||||
somewhat incomplete and meets only the "Full user recompilation" (2)
|
||||
recompilation guarantee by requiring the user to link against a
|
||||
different library in debug mode vs. release mode.</li>
|
||||
|
||||
<li><a href="http://www.metrowerks.com/mw/default.htm">Metrowerks
|
||||
CodeWarrior</a>: The C++ standard library that ships with Metrowerks
|
||||
CodeWarrior includes a debug mode. It is a full debug-mode
|
||||
implementation (including debugging for CodeWarrior extensions) and
|
||||
is easy to use, although it meets only the "Full recompilation" (1)
|
||||
recompilation guarantee.</li>
|
||||
</ul>
|
||||
|
||||
<h2><a name="design">Debug mode design methodology</a></h2>
|
||||
<p>This section provides an overall view of the design of the
|
||||
libstdc++ debug mode and details the relationship between design
|
||||
decisions and the stated design goals.</p>
|
||||
|
||||
<h3><a name="wrappers">The wrapper model</a></h3>
|
||||
<p>The libstdc++ debug mode uses a wrapper model where the debugging
|
||||
versions of library components (e.g., iterators and containers) form
|
||||
a layer on top of the release versions of the library
|
||||
components. The debugging components first verify that the operation
|
||||
is correct (aborting with a diagnostic if an error is found) and
|
||||
will then forward to the underlying release-mode container that will
|
||||
perform the actual work. This design decision ensures that we cannot
|
||||
regress release-mode performance (because the release-mode
|
||||
containers are left untouched) and partially enables <a
|
||||
href="#mixing">mixing debug and release code</a> at link time,
|
||||
although that will not be discussed at this time.</p>
|
||||
|
||||
<p>Two types of wrappers are used in the implementation of the debug
|
||||
mode: container wrappers and iterator wrappers. The two types of
|
||||
wrappers interact to maintain relationships between iterators and
|
||||
their associated containers, which are necessary to detect certain
|
||||
types of standard library usage errors such as dereferencing
|
||||
past-the-end iterators or inserting into a container using an
|
||||
iterator from a different container.</p>
|
||||
|
||||
<h4><a name="safe_iterator">Safe iterators</a></h4>
|
||||
<p>Iterator wrappers provide a debugging layer over any iterator that
|
||||
is attached to a particular container, and will manage the
|
||||
information detailing the iterator's state (singular,
|
||||
dereferenceable, etc.) and tracking the container to which the
|
||||
iterator is attached. Because iterators have a well-defined, common
|
||||
interface the iterator wrapper is implemented with the iterator
|
||||
adaptor class template <code>__gnu_debug::_Safe_iterator</code>,
|
||||
which takes two template parameters:</p>
|
||||
|
||||
<ul>
|
||||
<li><code>Iterator</code>: The underlying iterator type, which must
|
||||
be either the <code>iterator</code> or <code>const_iterator</code>
|
||||
typedef from the sequence type this iterator can reference.</li>
|
||||
|
||||
<li><code>Sequence</code>: The type of sequence that this iterator
|
||||
references. This sequence must be a safe sequence (discussed below)
|
||||
whose <code>iterator</code> or <code>const_iterator</code> typedef
|
||||
is the type of the safe iterator.</li>
|
||||
</ul>
|
||||
|
||||
<h4><a name="safe_sequence">Safe sequences (containers)</a></h4>
|
||||
<p>Container wrappers provide a debugging layer over a particular
|
||||
container type. Because containers vary greatly in the member
|
||||
functions they support and the semantics of those member functions
|
||||
(especially in the area of iterator invalidation), container
|
||||
wrappers are tailored to the container they reference, e.g., the
|
||||
debugging version of <code>std::list</code> duplicates the entire
|
||||
interface of <code>std::list</code>, adding additional semantic
|
||||
checks and then forwarding operations to the
|
||||
real <code>std::list</code> (a public base class of the debugging
|
||||
version) as appropriate. However, all safe containers inherit from
|
||||
the class template <code>__gnu_debug::_Safe_sequence</code>,
|
||||
instantiated with the type of the safe container itself (an instance
|
||||
of the curiously recurring template pattern).</p>
|
||||
|
||||
<p>The iterators of a container wrapper will be
|
||||
<a href="#safe_iterator">safe iterators</a> that reference sequences
|
||||
of this type and wrap the iterators provided by the release-mode
|
||||
base class. The debugging container will use only the safe
|
||||
iterators within its own interface (therefore requiring the user to
|
||||
use safe iterators, although this does not change correct user
|
||||
code) and will communicate with the release-mode base class with
|
||||
only the underlying, unsafe, release-mode iterators that the base
|
||||
class exports.</p>
|
||||
|
||||
<p> The debugging version of <code>std::list</code> will have the
|
||||
following basic structure:</p>
|
||||
|
||||
<pre>
|
||||
template<typename _Tp, typename _Allocator = allocator<_Tp>
|
||||
class debug-list :
|
||||
public release-list<_Tp, _Allocator>,
|
||||
public __gnu_debug::_Safe_sequence<debug-list<_Tp, _Allocator> >
|
||||
{
|
||||
typedef release-list<_Tp, _Allocator> _Base;
|
||||
typedef debug-list<_Tp, _Allocator> _Self;
|
||||
|
||||
public:
|
||||
typedef __gnu_debug::_Safe_iterator<typename _Base::iterator, _Self> iterator;
|
||||
typedef __gnu_debug::_Safe_iterator<typename _Base::const_iterator, _Self> const_iterator;
|
||||
|
||||
// duplicate std::list interface with debugging semantics
|
||||
};
|
||||
</pre>
|
||||
|
||||
<h3><a name="precondition">Precondition checking</a></h3>
|
||||
<p>The debug mode operates primarily by checking the preconditions of
|
||||
all standard library operations that it supports. Preconditions that
|
||||
are always checked (regardless of whether or not we are in debug
|
||||
mode) are checked via the <code>__check_xxx</code> macros defined
|
||||
and documented in the source
|
||||
file <code>include/debug/debug.h</code>. Preconditions that may or
|
||||
may not be checked, depending on the debug-mode
|
||||
macro <code>_GLIBCXX_DEBUG</code>, are checked via
|
||||
the <code>__requires_xxx</code> macros defined and documented in the
|
||||
same source file. Preconditions are validated using any additional
|
||||
information available at run-time, e.g., the containers that are
|
||||
associated with a particular iterator, the position of the iterator
|
||||
within those containers, the distance between two iterators that may
|
||||
form a valid range, etc. In the absence of suitable information,
|
||||
e.g., an input iterator that is not a safe iterator, these
|
||||
precondition checks will silently succeed.</p>
|
||||
|
||||
<p>The majority of precondition checks use the aforementioned macros,
|
||||
which have the secondary benefit of having prewritten debug
|
||||
messages that use information about the current status of the
|
||||
objects involved (e.g., whether an iterator is singular or what
|
||||
sequence it is attached to) along with some static information
|
||||
(e.g., the names of the function parameters corresponding to the
|
||||
objects involved). When not using these macros, the debug mode uses
|
||||
either the debug-mode assertion
|
||||
macro <code>_GLIBCXX_DEBUG_ASSERT</code> , its pedantic
|
||||
cousin <code>_GLIBCXX_DEBUG_PEDASSERT</code>, or the assertion
|
||||
check macro that supports more advance formulation of error
|
||||
messages, <code>_GLIBCXX_DEBUG_VERIFY</code>. These macros are
|
||||
documented more thoroughly in the debug mode source code.</p>
|
||||
|
||||
<h3><a name="coexistence">Release- and debug-mode coexistence</a></h3>
|
||||
<p>The libstdc++ debug mode is the first debug mode we know of that
|
||||
is able to provide the "Per-use recompilation" (4) guarantee, that
|
||||
allows release-compiled and debug-compiled code to be linked and
|
||||
executed together without causing unpredictable behavior. This
|
||||
guarantee minimizes the recompilation that users are required to
|
||||
perform, shortening the detect-compile-debug bughunting cycle
|
||||
and making the debug mode easier to incorporate into development
|
||||
environments by minimizing dependencies.</p>
|
||||
|
||||
<p>Achieving link- and run-time coexistence is not a trivial
|
||||
implementation task. To achieve this goal we required a small
|
||||
extension to the GNU C++ compiler (described in the GCC Manual for
|
||||
C++ Extensions, see <a
|
||||
href="http://gcc.gnu.org/onlinedocs/gcc/Strong-Using.html">strong
|
||||
using</a>), and a complex organization of debug- and
|
||||
release-modes. The end result is that we have achieved per-use
|
||||
recompilation but have had to give up some checking of the
|
||||
<code>std::basic_string</code> class template (namely, safe
|
||||
iterators).
|
||||
</p>
|
||||
|
||||
<h4><a name="compile_coexistence">Compile-time coexistence of release- and
|
||||
debug-mode components</a></h4>
|
||||
<p>Both the release-mode components and the debug-mode
|
||||
components need to exist within a single translation unit so that
|
||||
the debug versions can wrap the release versions. However, only one
|
||||
of these components should be user-visible at any particular
|
||||
time with the standard name, e.g., <code>std::list</code>. </p>
|
||||
|
||||
<p>In release mode, we define only the release-mode version of the
|
||||
component with its standard name and do not include the debugging
|
||||
component at all. The release mode version is defined within the
|
||||
namespace <code>std</code>. Minus the namespace associations, this
|
||||
method leaves the behavior of release mode completely unchanged from
|
||||
its behavior prior to the introduction of the libstdc++ debug
|
||||
mode. Here's an example of what this ends up looking like, in
|
||||
C++.</p>
|
||||
|
||||
<pre>
|
||||
namespace std
|
||||
{
|
||||
template<typename _Tp, typename _Alloc = allocator<_Tp> >
|
||||
class list
|
||||
{
|
||||
// ...
|
||||
};
|
||||
} // namespace std
|
||||
</pre>
|
||||
|
||||
<p>In debug mode we include the release-mode container (which is now
|
||||
defined in in the namespace <code>__norm</code>) and also the
|
||||
debug-mode container. The debug-mode container is defined within the
|
||||
namespace <code>__debug</code>, which is associated with namespace
|
||||
<code>std</code> via the GNU namespace association extension. This
|
||||
method allows the debug and release versions of the same component to
|
||||
coexist at compile-time and link-time without causing an unreasonable
|
||||
maintenance burden, while minimizing confusion. Again, this boils down
|
||||
to C++ code as follows:</p>
|
||||
|
||||
<pre>
|
||||
namespace std
|
||||
{
|
||||
namespace __norm
|
||||
{
|
||||
template<typename _Tp, typename _Alloc = allocator<_Tp> >
|
||||
class list
|
||||
{
|
||||
// ...
|
||||
};
|
||||
} // namespace __gnu_norm
|
||||
|
||||
namespace __debug
|
||||
{
|
||||
template<typename _Tp, typename _Alloc = allocator<_Tp> >
|
||||
class list
|
||||
: public __norm::list<_Tp, _Alloc>,
|
||||
public __gnu_debug::_Safe_sequence<list<_Tp, _Alloc> >
|
||||
{
|
||||
// ...
|
||||
};
|
||||
} // namespace __norm
|
||||
|
||||
using namespace __debug __attribute__ ((strong));
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h4><a name="mixing">Link- and run-time coexistence of release- and
|
||||
debug-mode components</a></h4>
|
||||
|
||||
<p>Because each component has a distinct and separate release and
|
||||
debug implementation, there are are no issues with link-time
|
||||
coexistence: the separate namespaces result in different mangled
|
||||
names, and thus unique linkage.</p>
|
||||
|
||||
<p>However, components that are defined and used within the C++
|
||||
standard library itself face additional constraints. For instance,
|
||||
some of the member functions of <code> std::moneypunct</code> return
|
||||
<code>std::basic_string</code>. Normally, this is not a problem, but
|
||||
with a mixed mode standard library that could be using either
|
||||
debug-mode or release-mode <code> basic_string</code> objects, things
|
||||
get more complicated. As the return value of a function is not
|
||||
encoded into the mangled name, there is no way to specify a
|
||||
release-mode or a debug-mode string. In practice, this results in
|
||||
runtime errors. A simplified example of this problem is as follows.
|
||||
</p>
|
||||
|
||||
<p> Take this translation unit, compiled in debug-mode: </p>
|
||||
<pre>
|
||||
// -D_GLIBCXX_DEBUG
|
||||
#include <string>
|
||||
|
||||
std::string test02();
|
||||
|
||||
std::string test01()
|
||||
{
|
||||
return test02();
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test01();
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p> ... and linked to this translation unit, compiled in release mode:</p>
|
||||
|
||||
<pre>
|
||||
#include <string>
|
||||
|
||||
std::string
|
||||
test02()
|
||||
{
|
||||
return std::string("toast");
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p> For this reason we cannot easily provide safe iterators for
|
||||
the <code>std::basic_string</code> class template, as it is present
|
||||
throughout the C++ standard library. For instance, locale facets
|
||||
define typedefs that include <code>basic_string</code>: in a mixed
|
||||
debug/release program, should that typedef be based on the
|
||||
debug-mode <code>basic_string</code> or the
|
||||
release-mode <code>basic_string</code>? While the answer could be
|
||||
"both", and the difference hidden via renaming a la the
|
||||
debug/release containers, we must note two things about locale
|
||||
facets:</p>
|
||||
|
||||
<ol>
|
||||
<li>They exist as shared state: one can create a facet in one
|
||||
translation unit and access the facet via the same type name in a
|
||||
different translation unit. This means that we cannot have two
|
||||
different versions of locale facets, because the types would not be
|
||||
the same across debug/release-mode translation unit barriers.</li>
|
||||
|
||||
<li>They have virtual functions returning strings: these functions
|
||||
mangle in the same way regardless of the mangling of their return
|
||||
types (see above), and their precise signatures can be relied upon
|
||||
by users because they may be overridden in derived classes.</li>
|
||||
</ol>
|
||||
|
||||
<p>With the design of libstdc++ debug mode, we cannot effectively hide
|
||||
the differences between debug and release-mode strings from the
|
||||
user. Failure to hide the differences may result in unpredictable
|
||||
behavior, and for this reason we have opted to only
|
||||
perform <code>basic_string</code> changes that do not require ABI
|
||||
changes. The effect on users is expected to be minimal, as there are
|
||||
simple alternatives (e.g., <code>__gnu_debug::basic_string</code>),
|
||||
and the usability benefit we gain from the ability to mix debug- and
|
||||
release-compiled translation units is enormous.</p>
|
||||
|
||||
<h4><a name="coexistence_alt">Alternatives for Coexistence</a></h4>
|
||||
<p>The coexistence scheme above was chosen over many alternatives,
|
||||
including language-only solutions and solutions that also required
|
||||
extensions to the C++ front end. The following is a partial list of
|
||||
solutions, with justifications for our rejection of each.</p>
|
||||
|
||||
<ul>
|
||||
<li><em>Completely separate debug/release libraries</em>: This is by
|
||||
far the simplest implementation option, where we do not allow any
|
||||
coexistence of debug- and release-compiled translation units in a
|
||||
program. This solution has an extreme negative affect on usability,
|
||||
because it is quite likely that some libraries an application
|
||||
depends on cannot be recompiled easily. This would not meet
|
||||
our <b>usability</b> or <b>minimize recompilation</b> criteria
|
||||
well.</li>
|
||||
|
||||
<li><em>Add a <code>Debug</code> boolean template parameter</em>:
|
||||
Partial specialization could be used to select the debug
|
||||
implementation when <code>Debug == true</code>, and the state
|
||||
of <code>_GLIBCXX_DEBUG</code> could decide whether the
|
||||
default <code>Debug</code> argument is <code>true</code>
|
||||
or <code>false</code>. This option would break conformance with the
|
||||
C++ standard in both debug <em>and</em> release modes. This would
|
||||
not meet our <b>correctness</b> criteria. </li>
|
||||
|
||||
<li><em>Packaging a debug flag in the allocators</em>: We could
|
||||
reuse the <code>Allocator</code> template parameter of containers
|
||||
by adding a sentinel wrapper <code>debug<></code> that
|
||||
signals the user's intention to use debugging, and pick up
|
||||
the <code>debug<></code> allocator wrapper in a partial
|
||||
specialization. However, this has two drawbacks: first, there is a
|
||||
conformance issue because the default allocator would not be the
|
||||
standard-specified <code>std::allocator<T></code>. Secondly
|
||||
(and more importantly), users that specify allocators instead of
|
||||
implicitly using the default allocator would not get debugging
|
||||
containers. Thus this solution fails the <b>correctness</b>
|
||||
criteria.</li>
|
||||
|
||||
<li><em>Define debug containers in another namespace, and employ
|
||||
a <code>using</code> declaration (or directive)</em>: This is an
|
||||
enticing option, because it would eliminate the need for
|
||||
the <code>link_name</code> extension by aliasing the
|
||||
templates. However, there is no true template aliasing mechanism
|
||||
is C++, because both <code>using</code> directives and using
|
||||
declarations disallow specialization. This method fails
|
||||
the <b>correctness</b> criteria.</li>
|
||||
|
||||
<li><em> Use implementation-specific properties of anonymous
|
||||
namespaces. </em>
|
||||
See <a
|
||||
href="http://gcc.gnu.org/ml/libstdc++/2003-08/msg00004.html"> this post
|
||||
</a>
|
||||
This method fails the <b>correctness</b> criteria.</li>
|
||||
|
||||
<li><em>Extension: allow reopening on namespaces</em>: This would
|
||||
allow the debug mode to effectively alias the
|
||||
namespace <code>std</code> to an internal namespace, such
|
||||
as <code>__gnu_std_debug</code>, so that it is completely
|
||||
separate from the release-mode <code>std</code> namespace. While
|
||||
this will solve some renaming problems and ensure that
|
||||
debug- and release-compiled code cannot be mixed unsafely, it ensures that
|
||||
debug- and release-compiled code cannot be mixed at all. For
|
||||
instance, the program would have two <code>std::cout</code>
|
||||
objects! This solution would fails the <b>minimize
|
||||
recompilation</b> requirement, because we would only be able to
|
||||
support option (1) or (2).</li>
|
||||
|
||||
<li><em>Extension: use link name</em>: This option involves
|
||||
complicated re-naming between debug-mode and release-mode
|
||||
components at compile time, and then a g++ extension called <em>
|
||||
link name </em> to recover the original names at link time. There
|
||||
are two drawbacks to this approach. One, it's very verbose,
|
||||
relying on macro renaming at compile time and several levels of
|
||||
include ordering. Two, ODR issues remained with container member
|
||||
functions taking no arguments in mixed-mode settings resulting in
|
||||
equivalent link names, <code> vector::push_back() </code> being
|
||||
one example.
|
||||
See <a
|
||||
href="http://gcc.gnu.org/ml/libstdc++/2003-08/msg00177.html">link
|
||||
name</a> </li>
|
||||
</ul>
|
||||
|
||||
<p>Other options may exist for implementing the debug mode, many of
|
||||
which have probably been considered and others that may still be
|
||||
lurking. This list may be expanded over time to include other
|
||||
options that we could have implemented, but in all cases the full
|
||||
ramifications of the approach (as measured against the design goals
|
||||
for a libstdc++ debug mode) should be considered first. The DejaGNU
|
||||
testsuite includes some testcases that check for known problems with
|
||||
some solutions (e.g., the <code>using</code> declaration solution
|
||||
that breaks user specialization), and additional testcases will be
|
||||
added as we are able to identify other typical problem cases. These
|
||||
test cases will serve as a benchmark by which we can compare debug
|
||||
mode implementations.</p>
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<hr />
|
||||
<p class="fineprint"><em>
|
||||
See <a href="17_intro/license.html">license.html</a> for copying conditions.
|
||||
Comments and suggestions are welcome, and may be sent to
|
||||
<a href="mailto:libstdc++@gcc.gnu.org">the libstdc++ mailing list</a>.
|
||||
</em></p>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,675 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
|
||||
<meta name="AUTHOR" content="pme@gcc.gnu.org (Phil Edwards)" />
|
||||
<meta name="KEYWORDS" content="HOWTO, libstdc++, GCC, g++, libg++, STL" />
|
||||
<meta name="DESCRIPTION" content="Notes for the libstdc++ extensions." />
|
||||
<meta name="GENERATOR" content="vi and eight fingers" />
|
||||
<title>libstdc++ HOWTO: Extensions</title>
|
||||
<link rel="StyleSheet" href="../lib3styles.css" type="text/css" />
|
||||
<link rel="Start" href="../documentation.html" type="text/html"
|
||||
title="GNU C++ Standard Library" />
|
||||
<link rel="Prev" href="../27_io/howto.html" type="text/html"
|
||||
title="Input/Output" />
|
||||
<link rel="Bookmark" href="sgiexts.html" type="text/html"
|
||||
title="SGI extensions" />
|
||||
<link rel="Bookmark" href="mt_allocator.html" type="text/html"
|
||||
title="__mt_alloc" />
|
||||
<link rel="Copyright" href="../17_intro/license.html" type="text/html" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 class="centered"><a name="top">Extensions</a></h1>
|
||||
|
||||
<p>Here we will make an attempt at describing the non-Standard extensions to
|
||||
the library. Some of these are from SGI's STL, some of these are GNU's,
|
||||
and some just seemed to appear on the doorstep.
|
||||
</p>
|
||||
<p><strong>Before you leap in and use these</strong>, be aware of two things:
|
||||
</p>
|
||||
<ol>
|
||||
<li>Non-Standard means exactly that. The behavior, and the very
|
||||
existence, of these extensions may change with little or no
|
||||
warning. (Ideally, the really good ones will appear in the next
|
||||
revision of C++.) Also, other platforms, other compilers, other
|
||||
versions of g++ or libstdc++ may not recognize these names, or
|
||||
treat them differently, or... </li>
|
||||
<li>You should know how to <a href="../faq/index.html#5_4">access
|
||||
these headers properly</a>. </li>
|
||||
</ol>
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
<hr />
|
||||
<h1>Contents</h1>
|
||||
<ul>
|
||||
<li><a href="#1">Ropes and trees and hashes, oh my!</a></li>
|
||||
<li><a href="#2">Added members and types</a></li>
|
||||
<li><a href="mt_allocator.html"><code>__mt_alloc</code> </a></li>
|
||||
<li><a href="#4">Compile-time checks</a></li>
|
||||
<li><a href="#5">LWG Issues</a></li>
|
||||
<li><a href="../18_support/howto.html#6">Demangling</a></li>
|
||||
</ul>
|
||||
|
||||
<hr />
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<h2><a name="1">Ropes and trees and hashes, oh my!</a></h2>
|
||||
<p>The SGI headers</p>
|
||||
<pre>
|
||||
<hash_map>
|
||||
<hash_set>
|
||||
<rope>
|
||||
<slist>
|
||||
<rb_tree>
|
||||
</pre>
|
||||
<p>are all here;
|
||||
<code><hash_map></code> and <code><hash_set></code>
|
||||
are deprecated but available as backwards-compatible extensions,
|
||||
as discussed further below. <code><rope></code> is the
|
||||
SGI specialization for large strings ("rope,"
|
||||
"large strings," get it? Love that geeky humor.)
|
||||
<code><slist></code> is a singly-linked list, for when the
|
||||
doubly-linked <code>list<></code> is too much space
|
||||
overhead, and <code><rb_tree></code> exposes the red-black
|
||||
tree classes used in the implementation of the standard maps and
|
||||
sets.
|
||||
</p>
|
||||
<p>Each of the associative containers map, multimap, set, and multiset
|
||||
have a counterpart which uses a
|
||||
<a href="http://www.sgi.com/tech/stl/HashFunction.html">hashing
|
||||
function</a> to do the arranging, instead of a strict weak ordering
|
||||
function. The classes take as one of their template parameters a
|
||||
function object that will return the hash value; by default, an
|
||||
instantiation of
|
||||
<a href="http://www.sgi.com/tech/stl/hash.html">hash</a>.
|
||||
You should specialize this functor for your class, or define your own,
|
||||
before trying to use one of the hashing classes.
|
||||
</p>
|
||||
<p>The hashing classes support all the usual associative container
|
||||
functions, as well as some extra constructors specifying the number
|
||||
of buckets, etc.
|
||||
</p>
|
||||
<p>Why would you want to use a hashing class instead of the
|
||||
"normal" implementations? Matt Austern writes:
|
||||
</p>
|
||||
<blockquote><em>[W]ith a well chosen hash function, hash tables
|
||||
generally provide much better average-case performance than binary
|
||||
search trees, and much worse worst-case performance. So if your
|
||||
implementation has hash_map, if you don't mind using nonstandard
|
||||
components, and if you aren't scared about the possibility of
|
||||
pathological cases, you'll probably get better performance from
|
||||
hash_map.</em></blockquote>
|
||||
|
||||
<p>Okay, about the SGI hashing classes... these classes have been
|
||||
deprecated by the unordered_set, unordered_multiset, unordered_map,
|
||||
unordered_multimap containers in TR1 and the upcoming C++0x, and
|
||||
may be removed in future releases.
|
||||
</p>
|
||||
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="2">Added members and types</a></h2>
|
||||
<p>Some of the classes in the Standard Library have additional
|
||||
publicly-available members, and some classes are themselves not in
|
||||
the standard. Of those, some are intended purely for the implementors,
|
||||
for example, additional typedefs. Those won't be described here
|
||||
(or anywhere else).
|
||||
</p>
|
||||
<ul>
|
||||
<li>The extensions added by SGI are so numerous that they have
|
||||
<a href="sgiexts.html">their own page</a>. Since the SGI STL is no
|
||||
longer actively maintained, we will try and keep this code working
|
||||
ourselves.</li>
|
||||
<li>Extensions allowing <code>filebuf</code>s to be constructed from
|
||||
stdio types are described in the
|
||||
<a href="../27_io/howto.html#11">chapter 27 notes</a>.</li>
|
||||
<li>The C++ Standard Library Technical Report adds many new features
|
||||
to the library, see <a href="../faq/index.html#5_5">FAQ 5.5</a>.</li>
|
||||
</ul>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="4">Compile-time checks</a></h2>
|
||||
<p>Currently libstdc++ uses the concept checkers from the Boost
|
||||
library to perform <a href="../19_diagnostics/howto.html#3">optional
|
||||
compile-time checking</a> of template instantiations of the standard
|
||||
containers. They are described in the linked-to page.
|
||||
</p>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="5">LWG Issues</a></h2>
|
||||
<p>Everybody's got issues. Even the C++ Standard Library.
|
||||
</p>
|
||||
<p>The Library Working Group, or LWG, is the ISO subcommittee responsible
|
||||
for making changes to the library. They periodically publish an
|
||||
Issues List containing problems and possible solutions. As they reach
|
||||
a consensus on proposed solutions, we often incorporate the solution
|
||||
into libstdc++.
|
||||
</p>
|
||||
<p>Here are the issues which have resulted in code changes to the library.
|
||||
The links are to the specific defect reports from a <strong>partial
|
||||
copy</strong> of the Issues List. You can read the full version online
|
||||
at the <a href="http://www.open-std.org/jtc1/sc22/wg21/">ISO C++
|
||||
Committee homepage</a>, linked to on the
|
||||
<a href="http://gcc.gnu.org/readings.html">GCC "Readings"
|
||||
page</a>. If
|
||||
you spend a lot of time reading the issues, we recommend downloading
|
||||
the ZIP file and reading them locally.
|
||||
</p>
|
||||
<p>(NB: <strong>partial copy</strong> means that not all links within
|
||||
the lwg-*.html pages will work.
|
||||
Specifically, links to defect reports that have not been accorded full
|
||||
DR status will probably break. Rather than trying to mirror the
|
||||
entire issues list on our overworked web server, we recommend you go
|
||||
to the LWG homepage instead.)
|
||||
</p>
|
||||
<p>
|
||||
If a DR is not listed here, we may simply not have gotten to it yet;
|
||||
feel free to submit a patch. Search the include/bits and src
|
||||
directories for appearances of _GLIBCXX_RESOLVE_LIB_DEFECTS for
|
||||
examples of style. Note that we usually do not make changes to the code
|
||||
until an issue has reached <a href="lwg-active.html#DR">DR</a> status.
|
||||
</p>
|
||||
<dl>
|
||||
<dt><a href="lwg-defects.html#5">5</a>:
|
||||
<em>string::compare specification questionable</em>
|
||||
</dt>
|
||||
<dd>This should be two overloaded functions rather than a single function.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#17">17</a>:
|
||||
<em>Bad bool parsing</em>
|
||||
</dt>
|
||||
<dd>Apparently extracting Boolean values was messed up...
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#19">19</a>:
|
||||
<em>"Noconv" definition too vague</em>
|
||||
</dt>
|
||||
<dd>If <code>codecvt::do_in</code> returns <code>noconv</code> there are
|
||||
no changes to the values in <code>[to, to_limit)</code>.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#22">22</a>:
|
||||
<em>Member open vs flags</em>
|
||||
</dt>
|
||||
<dd>Re-opening a file stream does <em>not</em> clear the state flags.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#25">25</a>:
|
||||
<em>String operator<< uses width() value wrong</em>
|
||||
</dt>
|
||||
<dd>Padding issues.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#48">48</a>:
|
||||
<em>Use of non-existent exception constructor</em>
|
||||
</dt>
|
||||
<dd>An instance of <code>ios_base::failure</code> is constructed instead.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#49">49</a>:
|
||||
<em>Underspecification of ios_base::sync_with_stdio</em>
|
||||
</dt>
|
||||
<dd>The return type is the <em>previous</em> state of synchronization.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#50">50</a>:
|
||||
<em>Copy constructor and assignment operator of ios_base</em>
|
||||
</dt>
|
||||
<dd>These members functions are declared <code>private</code> and are
|
||||
thus inaccessible. Specifying the correct semantics of
|
||||
"copying stream state" was deemed too complicated.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#60">60</a>:
|
||||
<em>What is a formatted input function?</em>
|
||||
</dt>
|
||||
<dd>This DR made many widespread changes to <code>basic_istream</code>
|
||||
and <code>basic_ostream</code> all of which have been implemented.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#63">63</a>:
|
||||
<em>Exception-handling policy for unformatted output</em>
|
||||
</dt>
|
||||
<dd>Make the policy consistent with that of formatted input, unformatted
|
||||
input, and formatted output.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#68">68</a>:
|
||||
<em>Extractors for char* should store null at end</em>
|
||||
</dt>
|
||||
<dd>And they do now. An editing glitch in the last item in the list of
|
||||
[27.6.1.2.3]/7.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#74">74</a>:
|
||||
<em>Garbled text for codecvt::do_max_length</em>
|
||||
</dt>
|
||||
<dd>The text of the standard was gibberish. Typos gone rampant.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#75">75</a>:
|
||||
<em>Contradiction in codecvt::length's argument types</em>
|
||||
</dt>
|
||||
<dd>Change the first parameter to <code>stateT&</code> and implement
|
||||
the new effects paragraph.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#83">83</a>:
|
||||
<em>string::npos vs. string::max_size()</em>
|
||||
</dt>
|
||||
<dd>Safety checks on the size of the string should test against
|
||||
<code>max_size()</code> rather than <code>npos</code>.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#90">90</a>:
|
||||
<em>Incorrect description of operator>> for strings</em>
|
||||
</dt>
|
||||
<dd>The effect contain <code>isspace(c,getloc())</code> which must be
|
||||
replaced by <code>isspace(c,is.getloc())</code>.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#91">91</a>:
|
||||
<em>Description of operator>> and getline() for string<>
|
||||
might cause endless loop</em>
|
||||
</dt>
|
||||
<dd>They behave as a formatted input function and as an unformatted
|
||||
input function, respectively (except that <code>getline</code> is
|
||||
not required to set <code>gcount</code>).
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#103">103</a>:
|
||||
<em>set::iterator is required to be modifiable, but this allows
|
||||
modification of keys.</em>
|
||||
</dt>
|
||||
<dd>For associative containers where the value type is the same as
|
||||
the key type, both <code>iterator</code> and <code>const_iterator
|
||||
</code> are constant iterators.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#109">109</a>:
|
||||
<em>Missing binders for non-const sequence elements</em>
|
||||
</dt>
|
||||
<dd>The <code>binder1st</code> and <code>binder2nd</code> didn't have an
|
||||
<code>operator()</code> taking a non-const parameter.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#110">110</a>:
|
||||
<em>istreambuf_iterator::equal not const</em>
|
||||
</dt>
|
||||
<dd>This was not a const member function. Note that the DR says to
|
||||
replace the function with a const one; we have instead provided an
|
||||
overloaded version with identical contents.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#117">117</a>:
|
||||
<em>basic_ostream uses nonexistent num_put member functions</em>
|
||||
</dt>
|
||||
<dd><code>num_put::put()</code> was overloaded on the wrong types.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#118">118</a>:
|
||||
<em>basic_istream uses nonexistent num_get member functions</em>
|
||||
</dt>
|
||||
<dd>Same as 117, but for <code>num_get::get()</code>.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#129">129</a>:
|
||||
<em>Need error indication from seekp() and seekg()</em>
|
||||
</dt>
|
||||
<dd>These functions set <code>failbit</code> on error now.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#136">136</a>:
|
||||
<em>seekp, seekg setting wrong streams?</em>
|
||||
</dt>
|
||||
<dd><code>seekp</code> should only set the output stream, and
|
||||
<code>seekg</code> should only set the input stream.
|
||||
</dd>
|
||||
|
||||
<!--<dt><a href="lwg-defects.html#159">159</a>:
|
||||
<em>Strange use of underflow()</em>
|
||||
</dt>
|
||||
<dd>In fstream.tcc, the basic_filebuf<>::showmanyc() function
|
||||
should probably not be calling <code>underflow()</code>.
|
||||
</dd> -->
|
||||
|
||||
<dt><a href="lwg-defects.html#167">167</a>:
|
||||
<em>Improper use of traits_type::length()</em>
|
||||
</dt>
|
||||
<dd><code>op<<</code> with a <code>const char*</code> was
|
||||
calculating an incorrect number of characters to write.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#169">169</a>:
|
||||
<em>Bad efficiency of overflow() mandated</em>
|
||||
</dt>
|
||||
<dd>Grow efficiently the internal array object.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#171">171</a>:
|
||||
<em>Strange seekpos() semantics due to joint position</em>
|
||||
</dt>
|
||||
<dd>Quite complex to summarize...
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#181">181</a>:
|
||||
<em>make_pair() unintended behavior</em>
|
||||
</dt>
|
||||
<dd>This function used to take its arguments as reference-to-const, now
|
||||
it copies them (pass by value).
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#195">195</a>:
|
||||
<em>Should basic_istream::sentry's constructor ever set eofbit?</em>
|
||||
</dt>
|
||||
<dd>Yes, it can, specifically if EOF is reached while skipping whitespace.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#211">211</a>:
|
||||
<em>operator>>(istream&, string&) doesn't set failbit</em>
|
||||
</dt>
|
||||
<dd>If nothing is extracted into the string, <code>op>></code> now
|
||||
sets <code>failbit</code> (which can cause an exception, etc., etc.).
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#214">214</a>:
|
||||
<em>set::find() missing const overload</em>
|
||||
</dt>
|
||||
<dd>Both <code>set</code> and <code>multiset</code> were missing
|
||||
overloaded find, lower_bound, upper_bound, and equal_range functions
|
||||
for const instances.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#231">231</a>:
|
||||
<em>Precision in iostream?</em>
|
||||
</dt>
|
||||
<dd>For conversion from a floating-point type, <code>str.precision()</code>
|
||||
is specified in the conversion specification.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-active.html#233">233</a>:
|
||||
<em>Insertion hints in associative containers</em>
|
||||
</dt>
|
||||
<dd>Implement N1780, first check before then check after, insert as close
|
||||
to hint as possible.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#235">235</a>:
|
||||
<em>No specification of default ctor for reverse_iterator</em>
|
||||
</dt>
|
||||
<dd>The declaration of <code>reverse_iterator</code> lists a default constructor.
|
||||
However, no specification is given what this constructor should do.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#241">241</a>:
|
||||
<em>Does unique_copy() require CopyConstructible and Assignable?</em>
|
||||
</dt>
|
||||
<dd>Add a helper for forward_iterator/output_iterator, fix the existing
|
||||
one for input_iterator/output_iterator to not rely on Assignability.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#243">243</a>:
|
||||
<em>get and getline when sentry reports failure</em>
|
||||
</dt>
|
||||
<dd>Store a null character only if the character array has a non-zero size.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#251">251</a>:
|
||||
<em>basic_stringbuf missing allocator_type</em>
|
||||
</dt>
|
||||
<dd>This nested typedef was originally not specified.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#253">253</a>:
|
||||
<em>valarray helper functions are almost entirely useless</em>
|
||||
</dt>
|
||||
<dd>Make the copy constructor and copy-assignment operator declarations
|
||||
public in gslice_array, indirect_array, mask_array, slice_array; provide
|
||||
definitions.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#265">265</a>:
|
||||
<em>std::pair::pair() effects overly restrictive</em>
|
||||
</dt>
|
||||
<dd>The default ctor would build its members from copies of temporaries;
|
||||
now it simply uses their respective default ctors.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#266">266</a>:
|
||||
<em>bad_exception::~bad_exception() missing Effects clause</em>
|
||||
</dt>
|
||||
<dd>The <code>bad_</code>* classes no longer have destructors (they
|
||||
are trivial), since no description of them was ever given.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#271">271</a>:
|
||||
<em>basic_iostream missing typedefs</em>
|
||||
</dt>
|
||||
<dd>The typedefs it inherits from its base classes can't be used, since
|
||||
(for example) <code>basic_iostream<T>::traits_type</code> is ambiguous.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#275">275</a>:
|
||||
<em>Wrong type in num_get::get() overloads</em>
|
||||
</dt>
|
||||
<dd>Similar to 118.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#280">280</a>:
|
||||
<em>Comparison of reverse_iterator to const reverse_iterator</em>
|
||||
</dt>
|
||||
<dd>Add global functions with two template parameters.
|
||||
(NB: not added for now a templated assignment operator)
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#292">292</a>:
|
||||
<em>Effects of a.copyfmt (a)</em>
|
||||
</dt>
|
||||
<dd>If <code>(this == &rhs)</code> do nothing.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#300">300</a>:
|
||||
<em>List::merge() specification incomplete</em>
|
||||
</dt>
|
||||
<dd>If <code>(this == &x)</code> do nothing.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#303">303</a>:
|
||||
<em>Bitset input operator underspecified</em>
|
||||
</dt>
|
||||
<dd>Basically, compare the input character to <code>is.widen(0)</code>
|
||||
and <code>is.widen(1)</code>.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#305">305</a>:
|
||||
<em>Default behavior of codecvt<wchar_t, char, mbstate_t>::length()</em>
|
||||
</dt>
|
||||
<dd>Do not specify what <code>codecvt<wchar_t, char, mbstate_t>::do_length</code>
|
||||
must return.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#328">328</a>:
|
||||
<em>Bad sprintf format modifier in money_put<>::do_put()</em>
|
||||
</dt>
|
||||
<dd>Change the format string to "%.0Lf".
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#365">365</a>:
|
||||
<em>Lack of const-qualification in clause 27</em>
|
||||
</dt>
|
||||
<dd>Add const overloads of <code>is_open</code>.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#389">389</a>:
|
||||
<em>Const overload of valarray::operator[] returns by value</em>
|
||||
</dt>
|
||||
<dd>Change it to return a <code>const T&</code>.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#402">402</a>:
|
||||
<em>Wrong new expression in [some_]allocator::construct</em>
|
||||
</dt>
|
||||
<dd>Replace "new" with "::new".
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#409">409</a>:
|
||||
<em>Closing an fstream should clear the error state</em>
|
||||
</dt>
|
||||
<dd>Have <code>open</code> clear the error flags.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-active.html#431">431</a>:
|
||||
<em>Swapping containers with unequal allocators</em>
|
||||
</dt>
|
||||
<dd>Implement Option 3, as per N1599.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#432">432</a>:
|
||||
<em>stringbuf::overflow() makes only one write position
|
||||
available</em>
|
||||
</dt>
|
||||
<dd>Implement the resolution, beyond DR 169.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#434">434</a>:
|
||||
<em>bitset::to_string() hard to use</em>
|
||||
</dt>
|
||||
<dd>Add three overloads, taking fewer template arguments.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#438">438</a>:
|
||||
<em>Ambiguity in the "do the right thing" clause</em>
|
||||
</dt>
|
||||
<dd>Implement the resolution, basically cast less.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#453">453</a>:
|
||||
<em>basic_stringbuf::seekoff need not always fail for an empty stream</em>
|
||||
</dt>
|
||||
<dd>Don't fail if the next pointer is null and newoff is zero.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#455">455</a>:
|
||||
<em>cerr::tie() and wcerr::tie() are overspecified</em>
|
||||
</dt>
|
||||
<dd>Initialize cerr tied to cout and wcerr tied to wcout.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#464">464</a>:
|
||||
<em>Suggestion for new member functions in standard containers</em>
|
||||
</dt>
|
||||
<dd>Add <code>data()</code> to <code>std::vector</code> and
|
||||
<code>at(const key_type&)</code> to <code>std::map</code>.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#508">508</a>:
|
||||
<em>Bad parameters for ranlux64_base_01</em>
|
||||
</dt>
|
||||
<dd>Fix the parameters.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-closed.html#512">512</a>:
|
||||
<em>Seeding subtract_with_carry_01 from a single unsigned long</em>
|
||||
</dt>
|
||||
<dd>Construct a <code>linear_congruential</code> engine and seed with it.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-closed.html#526">526</a>:
|
||||
<em>Is it undefined if a function in the standard changes in
|
||||
parameters?</em>
|
||||
</dt>
|
||||
<dd>Use &value.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#538">538</a>:
|
||||
<em>241 again: Does unique_copy() require CopyConstructible
|
||||
and Assignable?</em>
|
||||
</dt>
|
||||
<dd>In case of input_iterator/output_iterator rely on Assignability of
|
||||
input_iterator' value_type.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#541">541</a>:
|
||||
<em>shared_ptr template assignment and void</em>
|
||||
</dt>
|
||||
<dd>Add an auto_ptr<void> specialization.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#543">543</a>:
|
||||
<em>valarray slice default constructor</em>
|
||||
</dt>
|
||||
<dd>Follow the straightforward proposed resolution.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#586">586</a>:
|
||||
<em>string inserter not a formatted function</em>
|
||||
</dt>
|
||||
<dd>Change it to be a formatted output function (i.e. catch exceptions).
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-active.html#596">596</a>:
|
||||
<em>27.8.1.3 Table 112 omits "a+" and "a+b" modes</em>
|
||||
</dt>
|
||||
<dd>Add the missing modes to fopen_mode.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-defects.html#660">660</a>:
|
||||
<em>Missing bitwise operations</em>
|
||||
</dt>
|
||||
<dd>Add the missing operations.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-active.html#693">693</a>:
|
||||
<em>std::bitset::all() missing</em>
|
||||
</dt>
|
||||
<dd>Add it, consistently with the discussion.
|
||||
</dd>
|
||||
|
||||
<dt><a href="lwg-active.html#695">695</a>:
|
||||
<em>ctype<char>::classic_table() not accessible</em>
|
||||
</dt>
|
||||
<dd>Make the member functions table and classic_table public.
|
||||
</dd>
|
||||
<!--
|
||||
<dt><a href="lwg-defects.html#"></a>:
|
||||
<em></em>
|
||||
</dt>
|
||||
<dd>
|
||||
</dd>
|
||||
|
||||
-->
|
||||
</dl>
|
||||
<p>Return <a href="#top">to top of page</a> or
|
||||
<a href="../faq/index.html">to the FAQ</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<hr />
|
||||
<p class="fineprint"><em>
|
||||
See <a href="../17_intro/license.html">license.html</a> for copying conditions.
|
||||
Comments and suggestions are welcome, and may be sent to
|
||||
<a href="mailto:libstdc++@gcc.gnu.org">the libstdc++ mailing list</a>.
|
||||
</em></p>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,560 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta name="AUTHOR" content="Stefan Olsson <stefan@xapa.se>" />
|
||||
<meta name="KEYWORDS" content="c++, libstdc++, g++, allocator, memory" />
|
||||
<meta name="DESCRIPTION" content="Allocators and allocation" />
|
||||
<meta name="GENERATOR" content="emacs and ten fingers" />
|
||||
<title>A fixed-size, multi-thread optimized allocator</title>
|
||||
<link rel="StyleSheet" href="../lib3styles.css" type="text/css" />
|
||||
<link rel="Start" href="../documentation.html" type="text/html"
|
||||
title="GNU C++ Standard Library" />
|
||||
<link rel="Bookmark" href="howto.html" type="text/html" title="Extensions" />
|
||||
<link rel="Copyright" href="../17_intro/license.html" type="text/html" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 class="centered"><a name="top">A fixed-size, multi-thread optimized allocator</a></h1>
|
||||
|
||||
<p class="fineprint"><em>
|
||||
The latest version of this document is always available at
|
||||
<a href="http://gcc.gnu.org/onlinedocs/libstdc++/ext/mt_allocator.html">
|
||||
http://gcc.gnu.org/onlinedocs/libstdc++/ext/mt_allocator.html</a>.
|
||||
</em></p>
|
||||
|
||||
<p><em>
|
||||
To the <a href="http://gcc.gnu.org/libstdc++/">libstdc++ homepage</a>.
|
||||
</em></p>
|
||||
|
||||
<!-- ####################################################### -->
|
||||
<hr />
|
||||
<h3 class="left">
|
||||
<a name="intro">Introduction</a>
|
||||
</h3>
|
||||
|
||||
<p> The mt allocator [hereinafter referred to simply as "the
|
||||
allocator"] is a fixed size (power of two) allocator that was
|
||||
initially developed specifically to suit the needs of multi threaded
|
||||
applications [hereinafter referred to as an MT application]. Over time
|
||||
the allocator has evolved and been improved in many ways, in
|
||||
particular it now also does a good job in single threaded applications
|
||||
[hereinafter referred to as a ST application]. (Note: In this
|
||||
document, when referring to single threaded applications this also
|
||||
includes applications that are compiled with gcc without thread
|
||||
support enabled. This is accomplished using ifdef's on
|
||||
__GTHREADS). This allocator is tunable, very flexible, and capable of
|
||||
high-performance.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The aim of this document is to describe - from an application point of
|
||||
view - the "inner workings" of the allocator.
|
||||
</p>
|
||||
|
||||
<h3 class="left">
|
||||
<a name="design">Design Overview</a>
|
||||
</h3>
|
||||
|
||||
<p> There are three general components to the allocator: a datum
|
||||
describing the characteristics of the memory pool, a policy class
|
||||
containing this pool that links instantiation types to common or
|
||||
individual pools, and a class inheriting from the policy class that is
|
||||
the actual allocator.
|
||||
</p>
|
||||
|
||||
<p>The datum describing pools characteristics is
|
||||
</p>
|
||||
<pre>
|
||||
template<bool _Thread>
|
||||
class __pool
|
||||
</pre>
|
||||
<p> This class is parametrized on thread support, and is explicitly
|
||||
specialized for both multiple threads (with <code>bool==true</code>)
|
||||
and single threads (via <code>bool==false</code>.) It is possible to
|
||||
use a custom pool datum instead of the default class that is provided.
|
||||
</p>
|
||||
|
||||
<p> There are two distinct policy classes, each of which can be used
|
||||
with either type of underlying pool datum.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
template<bool _Thread>
|
||||
struct __common_pool_policy
|
||||
|
||||
template<typename _Tp, bool _Thread>
|
||||
struct __per_type_pool_policy
|
||||
</pre>
|
||||
|
||||
<p> The first policy, <code>__common_pool_policy</code>, implements a
|
||||
common pool. This means that allocators that are instantiated with
|
||||
different types, say <code>char</code> and <code>long</code> will both
|
||||
use the same pool. This is the default policy.
|
||||
</p>
|
||||
|
||||
<p> The second policy, <code>__per_type_pool_policy</code>, implements
|
||||
a separate pool for each instantiating type. Thus, <code>char</code>
|
||||
and <code>long</code> will use separate pools. This allows per-type
|
||||
tuning, for instance.
|
||||
</p>
|
||||
|
||||
<p> Putting this all together, the actual allocator class is
|
||||
</p>
|
||||
<pre>
|
||||
template<typename _Tp, typename _Poolp = __default_policy>
|
||||
class __mt_alloc : public __mt_alloc_base<_Tp>, _Poolp
|
||||
</pre>
|
||||
<p> This class has the interface required for standard library allocator
|
||||
classes, namely member functions <code>allocate</code> and
|
||||
<code>deallocate</code>, plus others.
|
||||
</p>
|
||||
|
||||
<h3 class="left">
|
||||
<a name="init">Tunable parameters</a>
|
||||
</h3>
|
||||
|
||||
<p>Certain allocation parameters can be modified, or tuned. There
|
||||
exists a nested <code>struct __pool_base::_Tune</code> that contains all
|
||||
these parameters, which include settings for
|
||||
</p>
|
||||
<ul>
|
||||
<li>Alignment </li>
|
||||
<li>Maximum bytes before calling <code>::operator new</code> directly</li>
|
||||
<li>Minimum bytes</li>
|
||||
<li>Size of underlying global allocations</li>
|
||||
<li>Maximum number of supported threads</li>
|
||||
<li>Migration of deallocations to the global free list</li>
|
||||
<li>Shunt for global <code>new</code> and <code>delete</code></li>
|
||||
</ul>
|
||||
<p>Adjusting parameters for a given instance of an allocator can only
|
||||
happen before any allocations take place, when the allocator itself is
|
||||
initialized. For instance:
|
||||
</p>
|
||||
<pre>
|
||||
#include <ext/mt_allocator.h>
|
||||
|
||||
struct pod
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
typedef pod value_type;
|
||||
typedef __gnu_cxx::__mt_alloc<value_type> allocator_type;
|
||||
typedef __gnu_cxx::__pool_base::_Tune tune_type;
|
||||
|
||||
tune_type t_default;
|
||||
tune_type t_opt(16, 5120, 32, 5120, 20, 10, false);
|
||||
tune_type t_single(16, 5120, 32, 5120, 1, 10, false);
|
||||
|
||||
tune_type t;
|
||||
t = allocator_type::_M_get_options();
|
||||
allocator_type::_M_set_options(t_opt);
|
||||
t = allocator_type::_M_get_options();
|
||||
|
||||
allocator_type a;
|
||||
allocator_type::pointer p1 = a.allocate(128);
|
||||
allocator_type::pointer p2 = a.allocate(5128);
|
||||
|
||||
a.deallocate(p1, 128);
|
||||
a.deallocate(p2, 5128);
|
||||
|
||||
return 0;
|
||||
}
|
||||
</pre>
|
||||
|
||||
<h3 class="left">
|
||||
<a name="init">Initialization</a>
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
The static variables (pointers to freelists, tuning parameters etc)
|
||||
are initialized as above, or are set to the global defaults.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The very first allocate() call will always call the
|
||||
_S_initialize_once() function. In order to make sure that this
|
||||
function is called exactly once we make use of a __gthread_once call
|
||||
in MT applications and check a static bool (_S_init) in ST
|
||||
applications.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The _S_initialize() function:
|
||||
- If the GLIBCXX_FORCE_NEW environment variable is set, it sets the bool
|
||||
_S_force_new to true and then returns. This will cause subsequent calls to
|
||||
allocate() to return memory directly from a new() call, and deallocate will
|
||||
only do a delete() call.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
- If the GLIBCXX_FORCE_NEW environment variable is not set, both ST and MT
|
||||
applications will:
|
||||
- Calculate the number of bins needed. A bin is a specific power of two size
|
||||
of bytes. I.e., by default the allocator will deal with requests of up to
|
||||
128 bytes (or whatever the value of _S_max_bytes is when _S_init() is
|
||||
called). This means that there will be bins of the following sizes
|
||||
(in bytes): 1, 2, 4, 8, 16, 32, 64, 128.
|
||||
|
||||
- Create the _S_binmap array. All requests are rounded up to the next
|
||||
"large enough" bin. I.e., a request for 29 bytes will cause a block from
|
||||
the "32 byte bin" to be returned to the application. The purpose of
|
||||
_S_binmap is to speed up the process of finding out which bin to use.
|
||||
I.e., the value of _S_binmap[ 29 ] is initialized to 5 (bin 5 = 32 bytes).
|
||||
</p>
|
||||
<p>
|
||||
- Create the _S_bin array. This array consists of bin_records. There will be
|
||||
as many bin_records in this array as the number of bins that we calculated
|
||||
earlier. I.e., if _S_max_bytes = 128 there will be 8 entries.
|
||||
Each bin_record is then initialized:
|
||||
- bin_record->first = An array of pointers to block_records. There will be
|
||||
as many block_records pointers as there are maximum number of threads
|
||||
(in a ST application there is only 1 thread, in a MT application there
|
||||
are _S_max_threads).
|
||||
This holds the pointer to the first free block for each thread in this
|
||||
bin. I.e., if we would like to know where the first free block of size 32
|
||||
for thread number 3 is we would look this up by: _S_bin[ 5 ].first[ 3 ]
|
||||
|
||||
The above created block_record pointers members are now initialized to
|
||||
their initial values. I.e. _S_bin[ n ].first[ n ] = NULL;
|
||||
</p>
|
||||
|
||||
<p>
|
||||
- Additionally a MT application will:
|
||||
- Create a list of free thread id's. The pointer to the first entry
|
||||
is stored in _S_thread_freelist_first. The reason for this approach is
|
||||
that the __gthread_self() call will not return a value that corresponds to
|
||||
the maximum number of threads allowed but rather a process id number or
|
||||
something else. So what we do is that we create a list of thread_records.
|
||||
This list is _S_max_threads long and each entry holds a size_t thread_id
|
||||
which is initialized to 1, 2, 3, 4, 5 and so on up to _S_max_threads.
|
||||
Each time a thread calls allocate() or deallocate() we call
|
||||
_S_get_thread_id() which looks at the value of _S_thread_key which is a
|
||||
thread local storage pointer. If this is NULL we know that this is a newly
|
||||
created thread and we pop the first entry from this list and saves the
|
||||
pointer to this record in the _S_thread_key variable. The next time
|
||||
we will get the pointer to the thread_record back and we use the
|
||||
thread_record->thread_id as identification. I.e., the first thread that
|
||||
calls allocate will get the first record in this list and thus be thread
|
||||
number 1 and will then find the pointer to its first free 32 byte block
|
||||
in _S_bin[ 5 ].first[ 1 ]
|
||||
When we create the _S_thread_key we also define a destructor
|
||||
(_S_thread_key_destr) which means that when the thread dies, this
|
||||
thread_record is returned to the front of this list and the thread id
|
||||
can then be reused if a new thread is created.
|
||||
This list is protected by a mutex (_S_thread_freelist_mutex) which is only
|
||||
locked when records are removed/added to the list.
|
||||
</p>
|
||||
<p>
|
||||
- Initialize the free and used counters of each bin_record:
|
||||
- bin_record->free = An array of size_t. This keeps track of the number
|
||||
of blocks on a specific thread's freelist in each bin. I.e., if a thread
|
||||
has 12 32-byte blocks on it's freelists and allocates one of these, this
|
||||
counter would be decreased to 11.
|
||||
|
||||
- bin_record->used = An array of size_t. This keeps track of the number
|
||||
of blocks currently in use of this size by this thread. I.e., if a thread
|
||||
has made 678 requests (and no deallocations...) of 32-byte blocks this
|
||||
counter will read 678.
|
||||
|
||||
The above created arrays are now initialized with their initial values.
|
||||
I.e. _S_bin[ n ].free[ n ] = 0;
|
||||
</p>
|
||||
<p>
|
||||
- Initialize the mutex of each bin_record: The bin_record->mutex
|
||||
is used to protect the global freelist. This concept of a global
|
||||
freelist is explained in more detail in the section "A multi
|
||||
threaded example", but basically this mutex is locked whenever a
|
||||
block of memory is retrieved or returned to the global freelist
|
||||
for this specific bin. This only occurs when a number of blocks
|
||||
are grabbed from the global list to a thread specific list or when
|
||||
a thread decides to return some blocks to the global freelist.
|
||||
</p>
|
||||
|
||||
<p> Notes about deallocation. This allocator does not explicitly
|
||||
release memory. Because of this, memory debugging programs like
|
||||
valgrind or purify may notice leaks: sorry about this
|
||||
inconvenience. Operating systems will reclaim allocated memory at
|
||||
program termination anyway. If sidestepping this kind of noise is
|
||||
desired, there are three options: use an allocator, like
|
||||
<code>new_allocator</code> that releases memory while debugging, use
|
||||
GLIBCXX_FORCE_NEW to bypass the allocator's internal pools, or use a
|
||||
custom pool datum that releases resources on destruction.</p>
|
||||
|
||||
<p>On systems with the function <code>__cxa_atexit</code>, the
|
||||
allocator can be forced to free all memory allocated before program
|
||||
termination with the member function
|
||||
<code>__pool_type::_M_destroy</code>. However, because this member
|
||||
function relies on the precise and exactly-conforming ordering of
|
||||
static destructors, including those of a static local
|
||||
<code>__pool</code> object, it should not be used, ever, on systems
|
||||
that don't have the necessary underlying support. In addition, in
|
||||
practice, forcing deallocation can be tricky, as it requires the
|
||||
<code>__pool</code> object to be fully-constructed before the object
|
||||
that uses it is fully constructed. For most (but not all) STL
|
||||
containers, this works, as an instance of the allocator is constructed
|
||||
as part of a container's constructor. However, this assumption is
|
||||
implementation-specific, and subject to change. For an example of a
|
||||
pool that frees memory, see the following
|
||||
<a href="http://gcc.gnu.org/viewcvs/trunk/libstdc%2B%2B-v3/testsuite/ext/mt_allocator/deallocate_local-6.cc?view=markup">
|
||||
example.</a>
|
||||
</p>
|
||||
|
||||
<h3 class="left">
|
||||
<a name="st_example">A single threaded example (and a primer for the multi threaded example!)</a>
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
Let's start by describing how the data on a freelist is laid out in memory.
|
||||
This is the first two blocks in freelist for thread id 3 in bin 3 (8 bytes):
|
||||
</p>
|
||||
<pre>
|
||||
+----------------+
|
||||
| next* ---------|--+ (_S_bin[ 3 ].first[ 3 ] points here)
|
||||
| | |
|
||||
| | |
|
||||
| | |
|
||||
+----------------+ |
|
||||
| thread_id = 3 | |
|
||||
| | |
|
||||
| | |
|
||||
| | |
|
||||
+----------------+ |
|
||||
| DATA | | (A pointer to here is what is returned to the
|
||||
| | | the application when needed)
|
||||
| | |
|
||||
| | |
|
||||
| | |
|
||||
| | |
|
||||
| | |
|
||||
| | |
|
||||
+----------------+ |
|
||||
+----------------+ |
|
||||
| next* |<-+ (If next == NULL it's the last one on the list)
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
+----------------+
|
||||
| thread_id = 3 |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
+----------------+
|
||||
| DATA |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
| |
|
||||
+----------------+
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
With this in mind we simplify things a bit for a while and say that there is
|
||||
only one thread (a ST application). In this case all operations are made to
|
||||
what is referred to as the global pool - thread id 0 (No thread may be
|
||||
assigned this id since they span from 1 to _S_max_threads in a MT application).
|
||||
</p>
|
||||
<p>
|
||||
When the application requests memory (calling allocate()) we first look at the
|
||||
requested size and if this is > _S_max_bytes we call new() directly and return.
|
||||
</p>
|
||||
<p>
|
||||
If the requested size is within limits we start by finding out from which
|
||||
bin we should serve this request by looking in _S_binmap.
|
||||
</p>
|
||||
<p>
|
||||
A quick look at _S_bin[ bin ].first[ 0 ] tells us if there are any blocks of
|
||||
this size on the freelist (0). If this is not NULL - fine, just remove the
|
||||
block that _S_bin[ bin ].first[ 0 ] points to from the list,
|
||||
update _S_bin[ bin ].first[ 0 ] and return a pointer to that blocks data.
|
||||
</p>
|
||||
<p>
|
||||
If the freelist is empty (the pointer is NULL) we must get memory from the
|
||||
system and build us a freelist within this memory. All requests for new memory
|
||||
is made in chunks of _S_chunk_size. Knowing the size of a block_record and
|
||||
the bytes that this bin stores we then calculate how many blocks we can create
|
||||
within this chunk, build the list, remove the first block, update the pointer
|
||||
(_S_bin[ bin ].first[ 0 ]) and return a pointer to that blocks data.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Deallocation is equally simple; the pointer is casted back to a block_record
|
||||
pointer, lookup which bin to use based on the size, add the block to the front
|
||||
of the global freelist and update the pointer as needed
|
||||
(_S_bin[ bin ].first[ 0 ]).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The decision to add deallocated blocks to the front of the freelist was made
|
||||
after a set of performance measurements that showed that this is roughly 10%
|
||||
faster than maintaining a set of "last pointers" as well.
|
||||
</p>
|
||||
|
||||
<h3 class="left">
|
||||
<a name="mt_example">A multi threaded example</a>
|
||||
</h3>
|
||||
|
||||
<p>
|
||||
In the ST example we never used the thread_id variable present in each block.
|
||||
Let's start by explaining the purpose of this in a MT application.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The concept of "ownership" was introduced since many MT applications
|
||||
allocate and deallocate memory to shared containers from different
|
||||
threads (such as a cache shared amongst all threads). This introduces
|
||||
a problem if the allocator only returns memory to the current threads
|
||||
freelist (I.e., there might be one thread doing all the allocation and
|
||||
thus obtaining ever more memory from the system and another thread
|
||||
that is getting a longer and longer freelist - this will in the end
|
||||
consume all available memory).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Each time a block is moved from the global list (where ownership is
|
||||
irrelevant), to a threads freelist (or when a new freelist is built
|
||||
from a chunk directly onto a threads freelist or when a deallocation
|
||||
occurs on a block which was not allocated by the same thread id as the
|
||||
one doing the deallocation) the thread id is set to the current one.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
What's the use? Well, when a deallocation occurs we can now look at
|
||||
the thread id and find out if it was allocated by another thread id
|
||||
and decrease the used counter of that thread instead, thus keeping the
|
||||
free and used counters correct. And keeping the free and used counters
|
||||
corrects is very important since the relationship between these two
|
||||
variables decides if memory should be returned to the global pool or
|
||||
not when a deallocation occurs.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
When the application requests memory (calling allocate()) we first
|
||||
look at the requested size and if this is > _S_max_bytes we call new()
|
||||
directly and return.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If the requested size is within limits we start by finding out from which
|
||||
bin we should serve this request by looking in _S_binmap.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
A call to _S_get_thread_id() returns the thread id for the calling thread
|
||||
(and if no value has been set in _S_thread_key, a new id is assigned and
|
||||
returned).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
A quick look at _S_bin[ bin ].first[ thread_id ] tells us if there are
|
||||
any blocks of this size on the current threads freelist. If this is
|
||||
not NULL - fine, just remove the block that _S_bin[ bin ].first[
|
||||
thread_id ] points to from the list, update _S_bin[ bin ].first[
|
||||
thread_id ], update the free and used counters and return a pointer to
|
||||
that blocks data.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If the freelist is empty (the pointer is NULL) we start by looking at
|
||||
the global freelist (0). If there are blocks available on the global
|
||||
freelist we lock this bins mutex and move up to block_count (the
|
||||
number of blocks of this bins size that will fit into a _S_chunk_size)
|
||||
or until end of list - whatever comes first - to the current threads
|
||||
freelist and at the same time change the thread_id ownership and
|
||||
update the counters and pointers. When the bins mutex has been
|
||||
unlocked, we remove the block that _S_bin[ bin ].first[ thread_id ]
|
||||
points to from the list, update _S_bin[ bin ].first[ thread_id ],
|
||||
update the free and used counters, and return a pointer to that blocks
|
||||
data.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The reason that the number of blocks moved to the current threads
|
||||
freelist is limited to block_count is to minimize the chance that a
|
||||
subsequent deallocate() call will return the excess blocks to the
|
||||
global freelist (based on the _S_freelist_headroom calculation, see
|
||||
below).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
However if there isn't any memory on the global pool we need to get
|
||||
memory from the system - this is done in exactly the same way as in a
|
||||
single threaded application with one major difference; the list built
|
||||
in the newly allocated memory (of _S_chunk_size size) is added to the
|
||||
current threads freelist instead of to the global.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The basic process of a deallocation call is simple: always add the
|
||||
block to the front of the current threads freelist and update the
|
||||
counters and pointers (as described earlier with the specific check of
|
||||
ownership that causes the used counter of the thread that originally
|
||||
allocated the block to be decreased instead of the current threads
|
||||
counter).
|
||||
</p>
|
||||
|
||||
<p>
|
||||
And here comes the free and used counters to service. Each time a
|
||||
deallocation() call is made, the length of the current threads
|
||||
freelist is compared to the amount memory in use by this thread.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Let's go back to the example of an application that has one thread
|
||||
that does all the allocations and one that deallocates. Both these
|
||||
threads use say 516 32-byte blocks that was allocated during thread
|
||||
creation for example. Their used counters will both say 516 at this
|
||||
point. The allocation thread now grabs 1000 32-byte blocks and puts
|
||||
them in a shared container. The used counter for this thread is now
|
||||
1516.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The deallocation thread now deallocates 500 of these blocks. For each
|
||||
deallocation made the used counter of the allocating thread is
|
||||
decreased and the freelist of the deallocation thread gets longer and
|
||||
longer. But the calculation made in deallocate() will limit the length
|
||||
of the freelist in the deallocation thread to _S_freelist_headroom %
|
||||
of it's used counter. In this case, when the freelist (given that the
|
||||
_S_freelist_headroom is at it's default value of 10%) exceeds 52
|
||||
(516/10) blocks will be returned to the global pool where the
|
||||
allocating thread may pick them up and reuse them.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In order to reduce lock contention (since this requires this bins
|
||||
mutex to be locked) this operation is also made in chunks of blocks
|
||||
(just like when chunks of blocks are moved from the global freelist to
|
||||
a threads freelist mentioned above). The "formula" used can probably
|
||||
be improved to further reduce the risk of blocks being "bounced back
|
||||
and forth" between freelists.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<p>Return <a href="#top">to the top of the page</a> or
|
||||
<a href="http://gcc.gnu.org/libstdc++/">to the libstdc++ homepage</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<hr />
|
||||
<p class="fineprint"><em>
|
||||
See <a href="../17_intro/license.html">license.html</a> for copying conditions.
|
||||
Comments and suggestions are welcome, and may be sent to
|
||||
<a href="mailto:libstdc++@gcc.gnu.org">the libstdc++ mailing list</a>.
|
||||
</em></p>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,593 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta name="AUTHOR" content="bkoz@gcc.gnu.org (Benjamin Kosnik)" />
|
||||
<meta name="KEYWORDS" content="c++, libstdc++, gdb, g++, debug" />
|
||||
<meta name="DESCRIPTION" content="The libstdc++ parallel mode." />
|
||||
<meta name="GENERATOR" content="emacs and ten fingers" />
|
||||
<title>The libstdc++ parallel mode</title>
|
||||
<link rel="StyleSheet" href="lib3styles.css" type="text/css" />
|
||||
<link rel="Copyright" href="17_intro/license.html" type="text/html" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 class="centered"><a name="top">The libstdc++ parallel mode</a></h1>
|
||||
|
||||
<p class="fineprint"><em>
|
||||
The latest version of this document is always available at
|
||||
<a href="http://gcc.gnu.org/onlinedocs/libstdc++/parallel_mode.html">
|
||||
http://gcc.gnu.org/onlinedocs/libstdc++/parallel_mode.html</a>.
|
||||
</em></p>
|
||||
|
||||
<p><em>
|
||||
To the <a href="http://gcc.gnu.org/libstdc++/">libstdc++ homepage</a>.
|
||||
</em></p>
|
||||
|
||||
<!-- ####################################################### -->
|
||||
<hr />
|
||||
<p> The libstdc++ parallel mode is an experimental parallel
|
||||
implementation of many algorithms the C++ Standard Library.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Several of the standard algorithms, for instance
|
||||
<code>std::sort</code>, are made parallel using OpenMP
|
||||
annotations. These parallel mode constructs and can be invoked by
|
||||
explicit source declaration or by compiling existing sources with a
|
||||
specific compiler flag.
|
||||
</p>
|
||||
|
||||
<h3 class="left"><a name="parallel">The libstdc++ parallel mode</a></h3>
|
||||
|
||||
<p>The libstdc++ parallel mode performs parallelization of algorithms,
|
||||
function objects, classes, and functions in the C++ Standard.</p>
|
||||
|
||||
<h4 class="left">Using the libstdc++ parallel mode</h4>
|
||||
|
||||
<p>To use the libstdc++ parallel mode, compile your application with
|
||||
the compiler flag <code>-D_GLIBCXX_PARALLEL -fopenmp</code>. This
|
||||
will link in <code>libgomp</code>, the GNU OpenMP <a
|
||||
href="http://gcc.gnu.org/onlinedocs/libgomp">implementation</a>,
|
||||
whose presence is mandatory. In addition, hardware capable of atomic
|
||||
operations is mandatory. Actually activating these atomic
|
||||
operations may require explicit compiler flags on some targets
|
||||
(like sparc and x86), such as <code>-march=i686</code>,
|
||||
<code>-march=native</code> or <code>-mcpu=v9</code>.
|
||||
</p>
|
||||
|
||||
<p>Note that the <code>_GLIBCXX_PARALLEL</code> define may change the
|
||||
sizes and behavior of standard class templates such as
|
||||
<code>std::search</code>, and therefore one can only link code
|
||||
compiled with parallel mode and code compiled without parallel mode
|
||||
if no instantiation of a container is passed between the two
|
||||
translation units. Parallel mode functionality has distinct linkage,
|
||||
and cannot be confused with normal mode symbols.</p>
|
||||
|
||||
|
||||
<p>The following library components in the include
|
||||
<code><numeric></code> are included in the parallel mode:</p>
|
||||
<ul>
|
||||
<li><code>std::accumulate</code></li>
|
||||
<li><code>std::adjacent_difference</code></li>
|
||||
<li><code>std::inner_product</code></li>
|
||||
<li><code>std::partial_sum</code></li>
|
||||
</ul>
|
||||
|
||||
<p>The following library components in the include
|
||||
<code><algorithm></code> are included in the parallel mode:</p>
|
||||
<ul>
|
||||
<li><code>std::adjacent_find</code></li>
|
||||
<li><code>std::count</code></li>
|
||||
<li><code>std::count_if</code></li>
|
||||
<li><code>std::equal</code></li>
|
||||
<li><code>std::find</code></li>
|
||||
<li><code>std::find_if</code></li>
|
||||
<li><code>std::find_first_of</code></li>
|
||||
<li><code>std::for_each</code></li>
|
||||
<li><code>std::generate</code></li>
|
||||
<li><code>std::generate_n</code></li>
|
||||
<li><code>std::lexicographical_compare</code></li>
|
||||
<li><code>std::mismatch</code></li>
|
||||
<li><code>std::search</code></li>
|
||||
<li><code>std::search_n</code></li>
|
||||
<li><code>std::transform</code></li>
|
||||
<li><code>std::replace</code></li>
|
||||
<li><code>std::replace_if</code></li>
|
||||
<li><code>std::max_element</code></li>
|
||||
<li><code>std::merge</code></li>
|
||||
<li><code>std::min_element</code></li>
|
||||
<li><code>std::nth_element</code></li>
|
||||
<li><code>std::partial_sort</code></li>
|
||||
<li><code>std::partition</code></li>
|
||||
<li><code>std::random_shuffle</code></li>
|
||||
<li><code>std::set_union</code></li>
|
||||
<li><code>std::set_intersection</code></li>
|
||||
<li><code>std::set_symmetric_difference</code></li>
|
||||
<li><code>std::set_difference</code></li>
|
||||
<li><code>std::sort</code></li>
|
||||
<li><code>std::stable_sort</code></li>
|
||||
<li><code>std::unique_copy</code></li>
|
||||
</ul>
|
||||
|
||||
<p>The following library components in the includes
|
||||
<code><set></code> and <code><map></code> are included in the parallel mode:</p>
|
||||
<ul>
|
||||
<li><code>std::(multi_)map/set<T>::(multi_)map/set(Iterator begin, Iterator end)</code> (bulk construction)</li>
|
||||
<li><code>std::(multi_)map/set<T>::insert(Iterator begin, Iterator end)</code> (bulk insertion)</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h4 class="left">Using the parallel algorithms without parallel mode</h4>
|
||||
|
||||
<p>When it is not feasible to recompile your entire application, or
|
||||
only specific algorithms need to be parallel-aware, individual
|
||||
parallel algorithms can be made available explicitly. These
|
||||
parallel algorithms are functionally equivalent to the standard
|
||||
drop-in algorithms used in parallel mode, but they are available in
|
||||
a separate namespace as GNU extensions and may be used in programs
|
||||
compiled with either release mode or with parallel mode. The
|
||||
following table provides the names and headers of the parallel
|
||||
algorithms:
|
||||
</p>
|
||||
|
||||
|
||||
<table title="Parallel algorithms" border="1">
|
||||
<tr>
|
||||
<th>Algorithm</th>
|
||||
<th>Header</th>
|
||||
<th>Parallel algorithm</th>
|
||||
<th>Parallel header</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>std::accumulate</td>
|
||||
<td><numeric></td>
|
||||
<td>__gnu_parallel::accumulate</td>
|
||||
<td><parallel/numeric></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>std::adjacent_difference</td>
|
||||
<td><numeric></td>
|
||||
<td>__gnu_parallel::adjacent_difference</td>
|
||||
<td><parallel/numeric></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>std::inner_product</td>
|
||||
<td><numeric></td>
|
||||
<td>__gnu_parallel::inner_product</td>
|
||||
<td><parallel/numeric></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>std::partial_sum</td>
|
||||
<td><numeric></td>
|
||||
<td>__gnu_parallel::partial_sum</td>
|
||||
<td><parallel/numeric></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>std::adjacent_find</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::adjacent_find</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::count</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::count</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::count_if</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::count_if</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::equal</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::equal</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::find</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::find</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::find_if</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::find_if</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::find_first_of</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::find_first_of</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::for_each</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::for_each</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::generate</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::generate</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::generate_n</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::generate_n</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::lexicographical_compare</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::lexicographical_compare</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::mismatch</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::mismatch</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::search</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::search</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::search_n</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::search_n</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::transform</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::transform</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::replace</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::replace</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::replace_if</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::replace_if</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::max_element</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::max_element</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::merge</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::merge</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::min_element</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::min_element</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::nth_element</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::nth_element</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::partial_sort</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::partial_sort</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::partition</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::partition</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::random_shuffle</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::random_shuffle</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::set_union</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::set_union</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::set_intersection</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::set_intersection</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::set_symmetric_difference</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::set_symmetric_difference</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::set_difference</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::set_difference</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::sort</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::sort</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::stable_sort</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::stable_sort</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>std::unique_copy</td>
|
||||
<td><algorithm></td>
|
||||
<td>__gnu_parallel::unique_copy</td>
|
||||
<td><parallel/algorithm></td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
|
||||
<h4 class="left">Parallel mode semantics</h4>
|
||||
|
||||
<p> The parallel mode STL algorithms are currently not exception-safe,
|
||||
i. e. user-defined functors must not throw exceptions.
|
||||
</p>
|
||||
|
||||
<p> Since the current GCC OpenMP implementation does not support
|
||||
OpenMP parallel regions in concurrent threads,
|
||||
it is not possible to call parallel STL algorithm in
|
||||
concurrent threads, either.
|
||||
It might work with other compilers, though.</p>
|
||||
|
||||
|
||||
<h4 class="left">Configuration and Tuning</h4>
|
||||
|
||||
<p> Some algorithm variants can be enabled/disabled/selected at compile-time.
|
||||
See <a href="latest-doxygen/compiletime__settings_8h.html">
|
||||
<code><compiletime_settings.h></code></a> and
|
||||
See <a href="latest-doxygen/compiletime__settings_8h.html">
|
||||
<code><features.h></code></a> for details.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To specify the number of threads to be used for an algorithm,
|
||||
use <code>omp_set_num_threads</code>.
|
||||
To force a function to execute sequentially,
|
||||
even though parallelism is switched on in general,
|
||||
add <code>__gnu_parallel::sequential_tag()</code>
|
||||
to the end of the argument list.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Parallelism always incurs some overhead. Thus, it is not
|
||||
helpful to parallelize operations on very small sets of data.
|
||||
There are measures to avoid parallelizing stuff that is not worth it.
|
||||
For each algorithm, a minimum problem size can be stated,
|
||||
usually using the variable
|
||||
<code>__gnu_parallel::Settings::[algorithm]_minimal_n</code>.
|
||||
Please see <a href="latest-doxygen/settings_8h.html">
|
||||
<code><settings.h></code></a> for details.</p>
|
||||
|
||||
|
||||
|
||||
<h4 class="left">Interface basics and general design</h4>
|
||||
|
||||
<p>All parallel algorithms are intended to have signatures that are
|
||||
equivalent to the ISO C++ algorithms replaced. For instance, the
|
||||
<code>std::adjacent_find</code> function is declared as:
|
||||
</p>
|
||||
<pre>
|
||||
namespace std
|
||||
{
|
||||
template<typename _FIter>
|
||||
_FIter
|
||||
adjacent_find(_FIter, _FIter);
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Which means that there should be something equivalent for the parallel
|
||||
version. Indeed, this is the case:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
namespace std
|
||||
{
|
||||
namespace __parallel
|
||||
{
|
||||
template<typename _FIter>
|
||||
_FIter
|
||||
adjacent_find(_FIter, _FIter);
|
||||
|
||||
...
|
||||
}
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>But.... why the elipses?
|
||||
</p>
|
||||
|
||||
<p> The elipses in the example above represent additional overloads
|
||||
required for the parallel version of the function. These additional
|
||||
overloads are used to dispatch calls from the ISO C++ function
|
||||
signature to the appropriate parallel function (or sequential
|
||||
function, if no parallel functions are deemed worthy), based on either
|
||||
compile-time or run-time conditions.
|
||||
</p>
|
||||
|
||||
<p> Compile-time conditions are referred to as "embarrassingly
|
||||
parallel," and are denoted with the appropriate dispatch object, ie
|
||||
one of <code>__gnu_parallel::sequential_tag</code>,
|
||||
<code>__gnu_parallel::parallel_tag</code>,
|
||||
<code>__gnu_parallel::balanced_tag</code>,
|
||||
<code>__gnu_parallel::unbalanced_tag</code>,
|
||||
<code>__gnu_parallel::omp_loop_tag</code>, or
|
||||
<code>__gnu_parallel::omp_loop_static_tag</code>.
|
||||
</p>
|
||||
|
||||
<p> Run-time conditions depend on the hardware being used, the number
|
||||
of threads available, etc., and are denoted by the use of the enum
|
||||
<code>__gnu_parallel::parallelism</code>. Values of this enum include
|
||||
<code>__gnu_parallel::sequential</code>,
|
||||
<code>__gnu_parallel::parallel_unbalanced</code>,
|
||||
<code>__gnu_parallel::parallel_balanced</code>,
|
||||
<code>__gnu_parallel::parallel_omp_loop</code>,
|
||||
<code>__gnu_parallel::parallel_omp_loop_static</code>, or
|
||||
<code>__gnu_parallel::parallel_taskqueue</code>.
|
||||
</p>
|
||||
|
||||
<p> Putting all this together, the general view of overloads for the
|
||||
parallel algorithms look like this:
|
||||
</p>
|
||||
<ul>
|
||||
<li>ISO C++ signature</li>
|
||||
<li>ISO C++ signature + sequential_tag argument</li>
|
||||
<li>ISO C++ signature + parallelism argument</li>
|
||||
</ul>
|
||||
|
||||
<p> Please note that the implementation may use additional functions
|
||||
(designated with the <code>_switch</code> suffix) to dispatch from the
|
||||
ISO C++ signature to the correct parallel version. Also, some of the
|
||||
algorithms do not have support for run-time conditions, so the last
|
||||
overload is therefore missing.
|
||||
</p>
|
||||
|
||||
|
||||
<h4 class="left">Relevant namespaces</h4>
|
||||
|
||||
<p> One namespace contain versions of code that are explicitly sequential:
|
||||
<code>__gnu_serial</code>.
|
||||
</p>
|
||||
|
||||
<p> Two namespaces contain the parallel mode:
|
||||
<code>std::__parallel</code> and <code>__gnu_parallel</code>.
|
||||
</p>
|
||||
|
||||
<p> Parallel implementations of standard components, including
|
||||
template helpers to select parallelism, are defined in <code>namespace
|
||||
std::__parallel</code>. For instance, <code>std::transform</code> from
|
||||
<algorithm> has a parallel counterpart in
|
||||
<code>std::__parallel::transform</code> from
|
||||
<parallel/algorithm>. In addition, these parallel
|
||||
implementations are injected into <code>namespace
|
||||
__gnu_parallel</code> with using declarations.
|
||||
</p>
|
||||
|
||||
<p> Support and general infrastructure is in <code>namespace
|
||||
__gnu_parallel</code>.
|
||||
</p>
|
||||
|
||||
<p> More information, and an organized index of types and functions
|
||||
related to the parallel mode on a per-namespace basis, can be found in
|
||||
the generated source documentation.
|
||||
</p>
|
||||
|
||||
<h4 class="left">Testing</h4>
|
||||
|
||||
<p> Both the normal conformance and regression tests and the
|
||||
supplemental performance tests work.</p>
|
||||
|
||||
<p> To run the conformance and regression tests with the parallel mode
|
||||
active,</p>
|
||||
<code>make check-parallel</code>
|
||||
|
||||
<p>The log and summary files for conformance testing are in the
|
||||
<code>testsuite/parallel</code> directory.</p>
|
||||
|
||||
<p> To run the performance tests with the parallel mode active, </p>
|
||||
<code>make check-performance-parallel</code>
|
||||
|
||||
<p>The result file for performance testing are in the
|
||||
<code>testsuite</code> directory, in the file
|
||||
<code>libstdc++_performance.sum</code>. In addition, the policy-based
|
||||
containers have their own visualizations, which have additional
|
||||
software dependencies than the usual bare-boned text file, and can be
|
||||
generated by using the <code>make doc-performance</code> rule in the
|
||||
testsuite's Makefile.</p>
|
||||
|
||||
<p>Return <a href="#top">to the top of the page</a> or
|
||||
<a href="http://gcc.gnu.org/libstdc++/">to the libstdc++ homepage</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<h4 class="left">References / Further Reading</h4>
|
||||
|
||||
<p>
|
||||
Johannes Singler, Peter Sanders, Felix Putze. The Multi-Core Standard Template Library. Euro-Par 2007: Parallel Processing. (LNCS 4641)
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Leonor Frias, Johannes Singler: Parallelization of Bulk Operations for STL Dictionaries. Workshop on Highly Parallel Processing on a Chip (HPPC) 2007. (LNCS)
|
||||
</p>
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<hr />
|
||||
<p class="fineprint"><em>
|
||||
See <a href="17_intro/license.html">license.html</a> for copying conditions.
|
||||
Comments and suggestions are welcome, and may be sent to
|
||||
<a href="mailto:libstdc++@gcc.gnu.org">the libstdc++ mailing list</a>.
|
||||
</em></p>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,253 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta name="AUTHOR" content="pme@gcc.gnu.org (Phil Edwards)" />
|
||||
<meta name="KEYWORDS" content="libstdc++, libstdc++, GCC, g++, STL, SGI" />
|
||||
<meta name="DESCRIPTION" content="SGI extensions preserved in libstdc++." />
|
||||
<meta name="GENERATOR" content="vi and eight fingers" />
|
||||
<title>HP/SGI STL extensions</title>
|
||||
<link rel="StyleSheet" href="../lib3styles.css" type="text/css" />
|
||||
<link rel="Start" href="../documentation.html" type="text/html"
|
||||
title="GNU C++ Standard Library" />
|
||||
<link rel="Subsection" href="sgiexts.html" type="text/html" title="Extensions" />
|
||||
<link rel="Bookmark" href="howto.html" type="text/html" title="Extensions" />
|
||||
<link rel="Copyright" href="../17_intro/license.html" type="text/html" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 class="centered"><a name="top">HP/SGI STL extensions</a></h1>
|
||||
|
||||
<p>This page describes the extensions that SGI made to the STL subset
|
||||
of the Standard C++ Library, which also includes work from the
|
||||
originating HP codebase. This work is the basis for much of
|
||||
libstdc++, and where possible these extensions have been
|
||||
preserved.
|
||||
</p>
|
||||
|
||||
<p>What follows is a listing of these extensions, according to the
|
||||
chapters of the library that they extend
|
||||
(see <a href="../documentation.html#3">the chapter-specific
|
||||
notes</a> for a description). Not every chapter has extensions,
|
||||
and existing extensions may be removed (or moved) as their
|
||||
functionality is standardized.
|
||||
</p>
|
||||
|
||||
<p>Descriptions range from the scanty to the verbose. Also check
|
||||
the <a href="../documentation.html#4">generated documentation</a>
|
||||
for notes and comments, especially for entries marked with '*'.
|
||||
For more complete doumentation, see the SGI website.
|
||||
For <em>really</em> complete documentation, consider perusing a
|
||||
copy of Matt Austern's book "Generic Programming and the STL."
|
||||
</p>
|
||||
|
||||
<p>Back to the <a href="howto.html">libstdc++ extensions</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
<hr />
|
||||
<h3><a name="ch20">Chapter 20</a></h3>
|
||||
<p>The <functional> header contains many additional functors and
|
||||
helper functions, extending section 20.3. They are implemented in the
|
||||
file stl_function.h:
|
||||
</p>
|
||||
<ul>
|
||||
<li><code>identity_element</code> for addition and multiplication. * </li>
|
||||
<li>The functor <code>identity</code>, whose <code>operator()</code>
|
||||
returns the argument unchanged. * </li>
|
||||
<li>Composition functors <code>unary_function</code> and
|
||||
<code>binary_function</code>, and their helpers <code>compose1</code>
|
||||
and <code>compose2</code>. * </li>
|
||||
<li><code>select1st</code> and <code>select2nd</code>, to strip pairs. * </li>
|
||||
<li><code>project1st</code> and <code>project2nd</code>. * </li>
|
||||
<li>A set of functors/functions which always return the same result. They
|
||||
are <code>constant_void_fun</code>, <code>constant_binary_fun</code>,
|
||||
<code>constant_unary_fun</code>, <code>constant0</code>,
|
||||
<code>constant1</code>, and <code>constant2</code>. * </li>
|
||||
<li>The class <code>subtractive_rng</code>. * </li>
|
||||
<li>mem_fun adaptor helpers <code>mem_fun1</code> and
|
||||
<code>mem_fun1_ref</code> are provided for backwards compatibility. </li>
|
||||
</ul>
|
||||
<p>20.4.1 can use several different allocators; they are described on the
|
||||
main extensions page.
|
||||
</p>
|
||||
<p>20.4.3 is extended with a special version of
|
||||
<code>get_temporary_buffer</code> taking a second argument. The argument
|
||||
is a pointer, which is ignored, but can be used to specify the template
|
||||
type (instead of using explicit function template arguments like the
|
||||
standard version does). That is, in addition to
|
||||
</p>
|
||||
<pre>
|
||||
get_temporary_buffer<int>(5);</pre>
|
||||
you can also use
|
||||
<pre>
|
||||
get_temporary_buffer(5, (int*)0);</pre>
|
||||
<p>A class <code>temporary_buffer</code> is given in stl_tempbuf.h. *
|
||||
</p>
|
||||
<p>The specialized algorithms of section 20.4.4 are extended with
|
||||
<code>uninitialized_copy_n</code>. *
|
||||
</p>
|
||||
<p>Return <a href="howto.html">to the main extensions page</a> or
|
||||
<a href="http://gcc.gnu.org/libstdc++/">to the homepage</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<hr />
|
||||
<h3><a name="ch23">Chapter 23</a></h3>
|
||||
<p>A few extensions and nods to backwards-compatibility have been made with
|
||||
containers. Those dealing with older SGI-style allocators are dealt with
|
||||
elsewhere. The remaining ones all deal with bits:
|
||||
</p>
|
||||
<p>The old pre-standard <code>bit_vector</code> class is present for
|
||||
backwards compatibility. It is simply a typedef for the
|
||||
<code>vector<bool></code> specialization.
|
||||
</p>
|
||||
<p>The <code>bitset</code> class has a number of extensions, described in the
|
||||
rest of this item. First, we'll mention that this implementation of
|
||||
<code>bitset<N></code> is specialized for cases where N number of
|
||||
bits will fit into a single word of storage. If your choice of N is
|
||||
within that range (<=32 on i686-pc-linux-gnu, for example), then all
|
||||
of the operations will be faster.
|
||||
</p>
|
||||
<p>There are
|
||||
versions of single-bit test, set, reset, and flip member functions which
|
||||
do no range-checking. If we call them member functions of an instantiation
|
||||
of "bitset<N>," then their names and signatures are:
|
||||
</p>
|
||||
<pre>
|
||||
bitset<N>& _Unchecked_set (size_t pos);
|
||||
bitset<N>& _Unchecked_set (size_t pos, int val);
|
||||
bitset<N>& _Unchecked_reset (size_t pos);
|
||||
bitset<N>& _Unchecked_flip (size_t pos);
|
||||
bool _Unchecked_test (size_t pos);</pre>
|
||||
<p>Note that these may in fact be removed in the future, although we have
|
||||
no present plans to do so (and there doesn't seem to be any immediate
|
||||
reason to).
|
||||
</p>
|
||||
<p>The semantics of member function <code>operator[]</code> are not specified
|
||||
in the C++ standard. A long-standing defect report calls for sensible
|
||||
obvious semantics, which are already implemented here: <code>op[]</code>
|
||||
on a const bitset returns a bool, and for a non-const bitset returns a
|
||||
<code>reference</code> (a nested type). However, this implementation does
|
||||
no range-checking on the index argument, which is in keeping with other
|
||||
containers' <code>op[]</code> requirements. The defect report's proposed
|
||||
resolution calls for range-checking to be done. We'll just wait and see...
|
||||
</p>
|
||||
<p>Finally, two additional searching functions have been added. They return
|
||||
the index of the first "on" bit, and the index of the first
|
||||
"on" bit that is after <code>prev</code>, respectively:
|
||||
</p>
|
||||
<pre>
|
||||
size_t _Find_first() const;
|
||||
size_t _Find_next (size_t prev) const;</pre>
|
||||
<p>The same caveat given for the _Unchecked_* functions applies here also.
|
||||
</p>
|
||||
<p>Return <a href="howto.html">to the main extensions page</a> or
|
||||
<a href="http://gcc.gnu.org/libstdc++/">to the homepage</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<hr />
|
||||
<h3><a name="ch24">Chapter 24</a></h3>
|
||||
<p>24.3.2 describes <code>struct iterator</code>, which didn't exist in the
|
||||
original HP STL implementation (the language wasn't rich enough at the
|
||||
time). For backwards compatibility, base classes are provided which
|
||||
declare the same nested typedefs:
|
||||
</p>
|
||||
<ul>
|
||||
<li>input_iterator</li>
|
||||
<li>output_iterator</li>
|
||||
<li>forward_iterator</li>
|
||||
<li>bidirectional_iterator</li>
|
||||
<li>random_access_iterator</li>
|
||||
</ul>
|
||||
<p>24.3.4 describes iterator operation <code>distance</code>, which takes
|
||||
two iterators and returns a result. It is extended by another signature
|
||||
which takes two iterators and a reference to a result. The result is
|
||||
modified, and the function returns nothing.
|
||||
</p>
|
||||
<p>Return <a href="howto.html">to the main extensions page</a> or
|
||||
<a href="http://gcc.gnu.org/libstdc++/">to the homepage</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<hr />
|
||||
<h3><a name="ch25">Chapter 25</a></h3>
|
||||
<p>25.1.6 (count, count_if) is extended with two more versions of count
|
||||
and count_if. The standard versions return their results. The
|
||||
additional signatures return void, but take a final parameter by
|
||||
reference to which they assign their results, e.g.,
|
||||
</p>
|
||||
<pre>
|
||||
void count (first, last, value, n);</pre>
|
||||
<p>25.2 (mutating algorithms) is extended with two families of signatures,
|
||||
random_sample and random_sample_n.
|
||||
</p>
|
||||
<p>25.2.1 (copy) is extended with
|
||||
</p>
|
||||
<pre>
|
||||
copy_n (_InputIter first, _Size count, _OutputIter result);</pre>
|
||||
<p>which copies the first 'count' elements at 'first' into 'result'.
|
||||
</p>
|
||||
<p>25.3 (sorting 'n' heaps 'n' stuff) is extended with some helper
|
||||
predicates. Look in the doxygen-generated pages for notes on these.
|
||||
</p>
|
||||
<ul>
|
||||
<li><code>is_heap</code> tests whether or not a range is a heap.</li>
|
||||
<li><code>is_sorted</code> tests whether or not a range is sorted in
|
||||
nondescending order.</li>
|
||||
</ul>
|
||||
<p>25.3.8 (lexigraphical_compare) is extended with
|
||||
</p>
|
||||
<pre>
|
||||
lexicographical_compare_3way(_InputIter1 first1, _InputIter1 last1,
|
||||
_InputIter2 first2, _InputIter2 last2)</pre>
|
||||
<p>which does... what?
|
||||
</p>
|
||||
<p>Return <a href="howto.html">to the main extensions page</a> or
|
||||
<a href="http://gcc.gnu.org/libstdc++/">to the homepage</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<hr />
|
||||
<h3><a name="ch26">Chapter 26</a></h3>
|
||||
<p>26.4, the generalized numeric operations such as accumulate, are extended
|
||||
with the following functions:
|
||||
</p>
|
||||
<pre>
|
||||
power (x, n);
|
||||
power (x, n, moniod_operation);</pre>
|
||||
<p>Returns, in FORTRAN syntax, "x ** n" where n>=0. In the
|
||||
case of n == 0, returns the <a href="#ch20">identity element</a> for the
|
||||
monoid operation. The two-argument signature uses multiplication (for
|
||||
a true "power" implementation), but addition is supported as well.
|
||||
The operation functor must be associative.
|
||||
</p>
|
||||
<p>The <code>iota</code> function wins the award for Extension With the
|
||||
Coolest Name. It "assigns sequentially increasing values to a range.
|
||||
That is, it assigns value to *first, value + 1 to *(first + 1) and so
|
||||
on." Quoted from SGI documentation.
|
||||
</p>
|
||||
<pre>
|
||||
void iota(_ForwardIter first, _ForwardIter last, _Tp value);</pre>
|
||||
<p>Return <a href="howto.html">to the main extensions page</a> or
|
||||
<a href="http://gcc.gnu.org/libstdc++/">to the homepage</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<hr />
|
||||
<p class="fineprint"><em>
|
||||
See <a href="../17_intro/license.html">license.html</a> for copying conditions.
|
||||
Comments and suggestions are welcome, and may be sent to
|
||||
<a href="mailto:libstdc++@gcc.gnu.org">the libstdc++ mailing list</a>.
|
||||
</em></p>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
File diff suppressed because it is too large
Load diff
43
libstdc++-v3/doc/html/index.html
Normal file
43
libstdc++-v3/doc/html/index.html
Normal file
|
@ -0,0 +1,43 @@
|
|||
<html>
|
||||
|
||||
<head>
|
||||
<title>The GNU C++ Library Documentation</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<!-- ==================================================================== -->
|
||||
|
||||
|
||||
<div>
|
||||
<h1>The GNU C++ Library Documentation</h1>
|
||||
|
||||
<p>Copyright 2008 FSF</p>
|
||||
|
||||
<p>
|
||||
Permission is granted to copy, distribute and/or modify this
|
||||
document under the terms of the GNU Free Documentation
|
||||
License, Version 1.2 or any later version published by the
|
||||
Free Software Foundation; with no Invariant Sections, with no
|
||||
Front-Cover Texts, and with no Back-Cover Texts.
|
||||
</p>
|
||||
<p>
|
||||
This is the top level of the libstdc++ documentation tree.
|
||||
The documentation is contained in three logically separate
|
||||
documents, as listed in the following Table of Contents.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p><b>Table of Contents</b></p>
|
||||
<dl>
|
||||
<dt><a href="manual/spine.html">Manual</a></dt>
|
||||
<dt><a href="faq.html">Frequently Asked Questions</a></dt>
|
||||
<dt><a href="api.html">API and Source Documentation</a></dt>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
|
@ -1,240 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta name="AUTHOR" content="pme@gcc.gnu.org (Phil Edwards)" />
|
||||
<meta name="KEYWORDS" content="libstdc++, libstdc++, GCC, g++" />
|
||||
<meta name="DESCRIPTION" content="README for the GNU libstdc++ effort." />
|
||||
<meta name="GENERATOR" content="vi and eight fingers" />
|
||||
<title>libstdc++ Installation Instructions</title>
|
||||
<link rel="StyleSheet" href="lib3styles.css" type="text/css" />
|
||||
<link rel="Copyright" href="17_intro/license.html" type="text/html" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 class="centered"><a name="top">Getting started: configure, build, install</a></h1>
|
||||
|
||||
<p class="fineprint"><em>
|
||||
The latest version of this document is always available at
|
||||
<a href="http://gcc.gnu.org/onlinedocs/libstdc++/install.html">
|
||||
http://gcc.gnu.org/onlinedocs/libstdc++/install.html</a>.
|
||||
</em></p>
|
||||
|
||||
<p><em>
|
||||
To the <a href="http://gcc.gnu.org/libstdc++/">libstdc++ homepage</a>.
|
||||
</em></p>
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
<hr />
|
||||
<h2>Contents</h2>
|
||||
|
||||
<p>Because libstdc++ is part of GCC, the primary source for
|
||||
installation instructions is
|
||||
<a href="http://gcc.gnu.org/install/">the GCC install page</a>.
|
||||
Additional data is given here only where it applies to libstdc++.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="#prereqs">Tools you will need beforehand</a></li>
|
||||
<li><a href="#config">Configuring</a></li>
|
||||
<li><a href="#usage">Using the library</a></li>
|
||||
</ul>
|
||||
|
||||
<hr />
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<h2><a name="prereqs">Tools you will need beforehand</a></h2>
|
||||
<p>The list of software needed to build the library is kept with the
|
||||
rest of the compiler, at
|
||||
<a href="http://gcc.gnu.org/install/prerequisites.html">
|
||||
http://gcc.gnu.org/install/prerequisites.html</a>. The same page
|
||||
also lists the tools you will need if you wish to modify the source.
|
||||
</p>
|
||||
|
||||
<p>As of GCC 4.0.1 the minimum version of binutils required to build
|
||||
libstdc++ is <code>2.15.90.0.1.1</code>. You can get snapshots
|
||||
(as well as releases) of binutils from
|
||||
<a href="ftp://sources.redhat.com/pub/binutils">
|
||||
ftp://sources.redhat.com/pub/binutils</a>.
|
||||
Older releases of libstdc++ do not require such a recent version,
|
||||
but to take full advantage of useful space-saving features and
|
||||
bug-fixes you should use a recent binutils if possible.
|
||||
The configure process will automatically detect and use these
|
||||
features if the underlying support is present.
|
||||
</p>
|
||||
|
||||
<p>Finally, a few system-specific requirements: </p>
|
||||
<dl>
|
||||
<dt> linux </dt>
|
||||
|
||||
<dd>If gcc 3.1.0 or later on is being used on linux, an attempt
|
||||
will be made to use "C" library functionality necessary for C++
|
||||
named locale support. For gcc 3.2.1 and later, this means that
|
||||
glibc 2.2.5 or later is required and the "C" library de_DE locale
|
||||
information must be installed.
|
||||
|
||||
<p>
|
||||
Note however that the sanity checks involving the de_DE locale are
|
||||
skipped when an explicit --enable-clocale=gnu configure option is
|
||||
used: only the basic checks are carried out, defending against
|
||||
misconfigurations.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If the 'gnu' locale model is being used, the following locales
|
||||
are used and tested in the libstdc++ testsuites. The first column
|
||||
is the name of the locale, the second is the character set it is
|
||||
expected to use.
|
||||
</p>
|
||||
<pre>
|
||||
de_DE ISO-8859-1
|
||||
de_DE@euro ISO-8859-15
|
||||
en_HK ISO-8859-1
|
||||
en_PH ISO-8859-1
|
||||
en_US ISO-8859-1
|
||||
en_US.ISO-8859-1 ISO-8859-1
|
||||
en_US.ISO-8859-15 ISO-8859-15
|
||||
en_US.UTF-8 UTF-8
|
||||
es_ES ISO-8859-1
|
||||
es_MX ISO-8859-1
|
||||
fr_FR ISO-8859-1
|
||||
fr_FR@euro ISO-8859-15
|
||||
is_IS UTF-8
|
||||
it_IT ISO-8859-1
|
||||
ja_JP.eucjp EUC-JP
|
||||
se_NO.UTF-8 UTF-8
|
||||
ta_IN UTF-8
|
||||
zh_TW BIG5
|
||||
</pre>
|
||||
<p>Failure to have the underlying "C" library locale
|
||||
information installed will mean that C++ named locales for the
|
||||
above regions will not work: because of this, the libstdc++
|
||||
testsuite will skip the named locale tests. If this isn't an
|
||||
issue, don't worry about it. If named locales are needed, the
|
||||
underlying locale information must be installed. Note that
|
||||
rebuilding libstdc++ after the "C" locales are installed is not
|
||||
necessary.
|
||||
</p>
|
||||
|
||||
<p>To install support for locales, do only one of the following:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li> install all locales
|
||||
<ul>
|
||||
<li>with RedHat Linux:
|
||||
<p> <code> export LC_ALL=C </code> </p>
|
||||
<p> <code> rpm -e glibc-common --nodeps </code> </p>
|
||||
<p> <code> rpm -i --define "_install_langs all"
|
||||
glibc-common-2.2.5-34.i386.rpm </code> </p>
|
||||
</li>
|
||||
<li> (instructions for other operating systems solicited) </li>
|
||||
</ul>
|
||||
</li>
|
||||
<li> install just the necessary locales
|
||||
<ul>
|
||||
<li>with Debian Linux:
|
||||
<p> Add the above list, as shown, to the file
|
||||
<code>/etc/locale.gen</code> </p>
|
||||
<p> run <code>/usr/sbin/locale-gen</code> </p>
|
||||
</li>
|
||||
<li> on most Unix-like operating systems:
|
||||
<p> <code> localedef -i de_DE -f ISO-8859-1 de_DE </code> </p>
|
||||
<p> (repeat for each entry in the above list) </p>
|
||||
</li>
|
||||
<li> (instructions for other operating systems solicited) </li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<hr />
|
||||
|
||||
<h2><a name="config">Configuring</a></h2>
|
||||
<p>If you have never done this before, you should read the basic
|
||||
<a href="http://gcc.gnu.org/install/">GCC Installation
|
||||
Instructions</a> first. Read <em>all of them</em>.
|
||||
<strong>Twice.</strong>
|
||||
</p>
|
||||
<p>When building libstdc++ you'll have to configure
|
||||
the entire <em>gccsrcdir</em> directory. The full list of libstdc++
|
||||
specific configuration options, not dependent on the specific compiler
|
||||
release being used, can be found <a href="configopts.html">here</a>.
|
||||
</p>
|
||||
<p>Consider possibly using --enable-languages=c++ to save time by only
|
||||
building the C++ language parts.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
cd <em>gccbuilddir</em>
|
||||
<em>gccsrcdir</em>/configure --prefix=<em>destdir</em> --other-opts...</pre>
|
||||
|
||||
|
||||
<hr />
|
||||
<h2><a name="usage">Using the library</a></h2>
|
||||
<h3>Find the new library at runtime (shared linking only)</h3>
|
||||
<p>If you only built a static library (libstdc++.a), or if you
|
||||
specified static linking, you don't have to worry about this.
|
||||
But if you built a shared library (libstdc++.so) and linked
|
||||
against it, then you will need to find that library when you
|
||||
run the executable.
|
||||
</p>
|
||||
<p>Methods vary for different platforms and different styles, but
|
||||
the usual ones are printed to the screen during installation.
|
||||
They include:
|
||||
</p>
|
||||
<ul>
|
||||
<li>At runtime set LD_LIBRARY_PATH in your environment correctly,
|
||||
so that the shared library for libstdc++ can be found and
|
||||
loaded. Be certain that you understand all of the other
|
||||
implications and behavior of LD_LIBRARY_PATH first (few
|
||||
people do, and they get into trouble).
|
||||
</li>
|
||||
<li>Compile the path to find the library at runtime into the
|
||||
program. This can be done by passing certain options to g++,
|
||||
which will in turn pass them on to the linker. The exact
|
||||
format of the options is dependent on which linker you use:
|
||||
<ul>
|
||||
<li>GNU ld (default on Linux):<code> -Wl,--rpath,<em>destdir</em>/lib</code></li>
|
||||
<li>IRIX ld:<code> -Wl,-rpath,<em>destdir</em>/lib</code></li>
|
||||
<li>Solaris ld:<code> -Wl,-R<em>destdir</em>/lib</code></li>
|
||||
<li>More...? Let us know!</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Use the <code>ldd(1)</code> utility to show which library the system
|
||||
thinks it will get at runtime.
|
||||
</p>
|
||||
<p>A libstdc++.la file is also installed, for use with Libtool. If
|
||||
you use Libtool to create your executables, these details are
|
||||
taken care of for you.
|
||||
</p>
|
||||
|
||||
|
||||
<!--
|
||||
<hr />
|
||||
<h2><a name=""></a></h2>
|
||||
<p>
|
||||
</p>
|
||||
|
||||
-->
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<hr />
|
||||
<p class="fineprint"><em>
|
||||
See <a href="17_intro/license.html">license.html</a> for copying conditions.
|
||||
Comments and suggestions are welcome, and may be sent to
|
||||
<a href="mailto:libstdc++@gcc.gnu.org">the libstdc++ mailing list</a>.
|
||||
</em></p>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
.centered { text-align: center }
|
||||
.tocheader { font-size: large }
|
||||
.fineprint { font-size: x-small }
|
||||
.larger { font-size: large }
|
||||
BODY { background: #FFFFFF }
|
||||
PRE { text-align: left ; margin-left: 1em }
|
|
@ -1,722 +0,0 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE html
|
||||
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||
<head>
|
||||
<meta name="AUTHOR" content="bkoz@gcc.gnu.org (Benjamin Kosnik)" />
|
||||
<meta name="KEYWORDS" content="c++, libstdc++, test, regression, g++" />
|
||||
<meta name="DESCRIPTION" content="README for the GNU libstdc++ effort." />
|
||||
<meta name="GENERATOR" content="vi and eight fingers" />
|
||||
<title>libstdc++ Testing Instructions</title>
|
||||
<link rel="StyleSheet" href="lib3styles.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h1 class="centered"><a name="top">Testing Details</a></h1>
|
||||
|
||||
<p class="fineprint"><em>
|
||||
The latest version of this document is always available at
|
||||
<a href="http://gcc.gnu.org/onlinedocs/libstdc++/test.html">
|
||||
http://gcc.gnu.org/onlinedocs/libstdc++/test.html</a>.
|
||||
</em></p>
|
||||
|
||||
<p><em>
|
||||
To the <a href="http://gcc.gnu.org/libstdc++/">libstdc++ homepage</a>.
|
||||
</em></p>
|
||||
|
||||
<!-- ####################################################### -->
|
||||
<hr />
|
||||
<h2>Contents</h2>
|
||||
<ul>
|
||||
<li><a href="#org">Testsuite organization and naming conventions</a></li>
|
||||
<li><a href="#util">Utilities: abicheck and libtestc++</a></li>
|
||||
<li><a href="#new">How to write a new test case</a></li>
|
||||
<li><a href="#check">Options for running the tests</a></li>
|
||||
<li><a href="#debug">Running debug-mode tests</a></li>
|
||||
<li><a href="#future">Future</a></li>
|
||||
<li><a href="#internals">DejaGNU internals</a></li>
|
||||
</ul>
|
||||
|
||||
<hr />
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<h2><a name="org">Testsuite organization and naming conventions</a></h2>
|
||||
<p>
|
||||
The directory <em>libsrcdir/testsuite</em> contains the
|
||||
individual test cases organized in sub-directories corresponding
|
||||
to chapters of the C++ standard (detailed below), the dejagnu
|
||||
test harness support files, and sources to various testsuite
|
||||
utilities that are packaged in a separate testing library.
|
||||
</p>
|
||||
|
||||
<p> All test cases for functionality required by the runtime
|
||||
components of the C++ standard (ISO 14882) are files within the
|
||||
following directories.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
17_intro
|
||||
18_support
|
||||
19_diagnostics
|
||||
20_util
|
||||
21_strings
|
||||
22_locale
|
||||
23_containers
|
||||
25_algorithms
|
||||
26_numerics
|
||||
27_io
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
In addition, the following directories include test files:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
tr1 Tests for components as described by the Technical Report on Standard Library Extensions (TR1).
|
||||
backward Tests for backwards compatibility and deprecated features.
|
||||
demangle Tests for __cxa_demangle, the IA 64 C++ ABI demangler
|
||||
ext Tests for extensions.
|
||||
performance Tests for performance analysis, and performance regressions.
|
||||
thread Tests for threads.
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Some directories don't have test files, but instead contain
|
||||
auxiliary information (<a href="#internals">more information</a>):
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
config Files for the dejagnu test harness.
|
||||
lib Files for the dejagnu test harness.
|
||||
libstdc++* Files for the dejagnu test harness.
|
||||
data Sample text files for testing input and output.
|
||||
util Files for libtestc++, utilities and testing routines.
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Within a directory that includes test files, there may be
|
||||
additional subdirectories, or files. Originally, test cases
|
||||
were appended to one file that represented a particular section
|
||||
of the chapter under test, and was named accordingly. For
|
||||
instance, to test items related to <code> 21.3.6.1 -
|
||||
basic_string::find [lib.string::find]</code> in the standard,
|
||||
the following was used:
|
||||
</p>
|
||||
<pre>
|
||||
21_strings/find.cc
|
||||
</pre>
|
||||
<p>
|
||||
However, that practice soon became a liability as the test cases
|
||||
became huge and unwieldy, and testing new or extended
|
||||
functionality (like wide characters or named locales) became
|
||||
frustrating, leading to aggressive pruning of test cases on some
|
||||
platforms that covered up implementation errors. Now, the test
|
||||
suite has a policy of one file, one test case, which solves the
|
||||
above issues and gives finer grained results and more manageable
|
||||
error debugging. As an example, the test case quoted above
|
||||
becomes:
|
||||
</p>
|
||||
<pre>
|
||||
21_strings/basic_string/find/char/1.cc
|
||||
21_strings/basic_string/find/char/2.cc
|
||||
21_strings/basic_string/find/char/3.cc
|
||||
21_strings/basic_string/find/wchar_t/1.cc
|
||||
21_strings/basic_string/find/wchar_t/2.cc
|
||||
21_strings/basic_string/find/wchar_t/3.cc
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
All new tests should be written with the policy of one test
|
||||
case, one file in mind.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In addition, there are some special names and suffixes that are
|
||||
used within the testsuite to designate particular kinds of
|
||||
tests.
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<em>_xin.cc</em>
|
||||
<p>
|
||||
This test case expects some kind of interactive input in order
|
||||
to finish or pass. At the moment, the interactive tests are not
|
||||
run by default. Instead, they are run by hand, like:
|
||||
</p>
|
||||
<pre>
|
||||
g++ 27_io/objects/char/3_xin.cc
|
||||
cat 27_io/objects/char/3_xin.in | a.out
|
||||
</pre>
|
||||
</li>
|
||||
<li>
|
||||
<em>.in</em>
|
||||
<p>
|
||||
This file contains the expected input for the corresponding <em>
|
||||
_xin.cc</em> test case.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<em>_neg.cc</em>
|
||||
<p>
|
||||
This test case is expected to fail: it's a negative test. At the
|
||||
moment, these are almost always compile time errors.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<em>char</em>
|
||||
<p>
|
||||
This can either be a directory name or part of a longer file
|
||||
name, and indicates that this file, or the files within this
|
||||
directory are testing the <code>char</code> instantiation of a
|
||||
template.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<em>wchar_t</em>
|
||||
<p>
|
||||
This can either be a directory name or part of a longer file
|
||||
name, and indicates that this file, or the files within this
|
||||
directory are testing the <code>wchar_t</code> instantiation of
|
||||
a template. Some hosts do not support <code>wchar_t</code>
|
||||
functionality, so for these targets, all of these tests will not
|
||||
be run.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<em>thread</em>
|
||||
<p>
|
||||
This can either be a directory name or part of a longer file
|
||||
name, and indicates that this file, or the files within this
|
||||
directory are testing situations where multiple threads are
|
||||
being used.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<em>performance</em>
|
||||
<p>
|
||||
This can either be an enclosing directory name or part of a
|
||||
specific file name. This indicates a test that is used to
|
||||
analyze runtime performance, for performance regression testing,
|
||||
or for other optimization related analysis. At the moment, these
|
||||
test cases are not run by default.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr />
|
||||
<h2><a name="util">Utilities: abi_check and libtestc++</a></h2>
|
||||
<p>
|
||||
The testsuite directory also contains some files that implement
|
||||
functionality that is intended to make writing test cases easier,
|
||||
or to avoid duplication, or to provide error checking in a way that
|
||||
is consistent across platforms and test harnesses. A stand-alone
|
||||
executable, called <em>abi_check</em>, and a static library called
|
||||
<em>libtestc++</em> are constructed. Both of these items are not
|
||||
installed, and only used during testing.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
These files include the following functionality:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
<em>testsuite_abi.h</em>,
|
||||
<em>testsuite_abi.cc</em>,
|
||||
<em>testsuite_abi_check.cc</em>
|
||||
<p>
|
||||
Creates the executable <em>abi_check</em>.
|
||||
Used to check correctness of symbol versioning, visibility of
|
||||
exported symbols, and compatibility on symbols in the shared
|
||||
library, for hosts that support this feature. More information
|
||||
can be found in the ABI documentation <a href="abi.html"> here</a>
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<em>testsuite_allocator.h</em>,
|
||||
<em>testsuite_allocator.cc</em>
|
||||
<p>
|
||||
Contains specialized allocators that keep track of construction
|
||||
and destruction. Also, support for overriding global new and
|
||||
delete operators, including verification that new and delete
|
||||
are called during execution, and that allocation over max_size
|
||||
fails.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<em>testsuite_character.h</em>
|
||||
<p>
|
||||
Contains <code>std::char_traits</code> and
|
||||
<code>std::codecvt</code> specializations for a user-defined
|
||||
POD.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<em>testsuite_hooks.h</em>,
|
||||
<em>testsuite_hooks.cc</em>
|
||||
<p>
|
||||
A large number of utilities, including:
|
||||
</p>
|
||||
<ul>
|
||||
<li>VERIFY</li>
|
||||
<li>set_memory_limits</li>
|
||||
<li>verify_demangle</li>
|
||||
<li>run_tests_wrapped_locale</li>
|
||||
<li>run_tests_wrapped_env</li>
|
||||
<li>try_named_locale</li>
|
||||
<li>try_mkfifo</li>
|
||||
<li>func_callback</li>
|
||||
<li>counter</li>
|
||||
<li>copy_tracker</li>
|
||||
<li>copy_constructor</li>
|
||||
<li>assignment_operator</li>
|
||||
<li>destructor</li>
|
||||
<li>pod_char, pod_int and associated char_traits specializations</li>
|
||||
</ul>
|
||||
<p></p>
|
||||
</li>
|
||||
<li>
|
||||
<em>testsuite_io.h</em>
|
||||
<p>
|
||||
Error, exception, and constraint checking for
|
||||
<code>std::streambuf, std::basic_stringbuf, std::basic_filebuf</code>.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<em>testsuite_iterators.h</em>
|
||||
<p>
|
||||
Wrappers for various iterators.
|
||||
</p>
|
||||
</li>
|
||||
<li>
|
||||
<em>testsuite_performance.h</em>
|
||||
<p>
|
||||
A number of class abstractions for performance counters, and
|
||||
reporting functions including:
|
||||
</p>
|
||||
<ul>
|
||||
<li>time_counter</li>
|
||||
<li>resource_counter</li>
|
||||
<li>report_performance</li>
|
||||
</ul>
|
||||
<p></p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<hr />
|
||||
<h2><a name="new">How to write a new test case</a></h2>
|
||||
|
||||
<p>
|
||||
The first step in making a new test case is to choose the correct
|
||||
directory and file name, given the organization as previously
|
||||
described.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
All files are copyright the FSF, and GPL'd: this is very
|
||||
important. The first copyright year should correspond to the date
|
||||
the file was checked in to SVN.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
As per the dejagnu instructions, always return 0 from main to
|
||||
indicate success.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
A bunch of utility functions and classes have already been
|
||||
abstracted out into the testsuite utility library, <code>
|
||||
libtestc++</code>. To use this functionality, just include the
|
||||
appropriate header file: the library or specific object files will
|
||||
automatically be linked in as part of the testsuite run.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For a test that needs to take advantage of the dejagnu test
|
||||
harness, what follows below is a list of special keyword that
|
||||
harness uses. Basically, a test case contains dg-keywords (see
|
||||
dg.exp) indicating what to do and what kinds of behavior are to be
|
||||
expected. New test cases should be written with the new style
|
||||
DejaGnu framework in mind.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To ease transition, here is the list of dg-keyword documentation
|
||||
lifted from dg.exp.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
# The currently supported options are:
|
||||
#
|
||||
# dg-prms-id N
|
||||
# set prms_id to N
|
||||
#
|
||||
# dg-options "options ..." [{ target selector }]
|
||||
# specify special options to pass to the tool (eg: compiler)
|
||||
#
|
||||
# dg-do do-what-keyword [{ target/xfail selector }]
|
||||
# `do-what-keyword' is tool specific and is passed unchanged to
|
||||
# ${tool}-dg-test. An example is gcc where `keyword' can be any of:
|
||||
# preprocess|compile|assemble|link|run
|
||||
# and will do one of: produce a .i, produce a .s, produce a .o,
|
||||
# produce an a.out, or produce an a.out and run it (the default is
|
||||
# compile).
|
||||
#
|
||||
# dg-error regexp comment [{ target/xfail selector } [{.|0|linenum}]]
|
||||
# indicate an error message <regexp> is expected on this line
|
||||
# (the test fails if it doesn't occur)
|
||||
# Linenum=0 for general tool messages (eg: -V arg missing).
|
||||
# "." means the current line.
|
||||
#
|
||||
# dg-warning regexp comment [{ target/xfail selector } [{.|0|linenum}]]
|
||||
# indicate a warning message <regexp> is expected on this line
|
||||
# (the test fails if it doesn't occur)
|
||||
#
|
||||
# dg-bogus regexp comment [{ target/xfail selector } [{.|0|linenum}]]
|
||||
# indicate a bogus error message <regexp> use to occur here
|
||||
# (the test fails if it does occur)
|
||||
#
|
||||
# dg-build regexp comment [{ target/xfail selector }]
|
||||
# indicate the build use to fail for some reason
|
||||
# (errors covered here include bad assembler generated, tool crashes,
|
||||
# and link failures)
|
||||
# (the test fails if it does occur)
|
||||
#
|
||||
# dg-excess-errors comment [{ target/xfail selector }]
|
||||
# indicate excess errors are expected (any line)
|
||||
# (this should only be used sparingly and temporarily)
|
||||
#
|
||||
# dg-output regexp [{ target selector }]
|
||||
# indicate the expected output of the program is <regexp>
|
||||
# (there may be multiple occurrences of this, they are concatenated)
|
||||
#
|
||||
# dg-final { tcl code }
|
||||
# add some tcl code to be run at the end
|
||||
# (there may be multiple occurrences of this, they are concatenated)
|
||||
# (unbalanced braces must be \-escaped)
|
||||
#
|
||||
# "{ target selector }" is a list of expressions that determine whether the
|
||||
# test succeeds or fails for a particular target, or in some cases whether the
|
||||
# option applies for a particular target. If the case of `dg-do' it specifies
|
||||
# whether the test case is even attempted on the specified target.
|
||||
#
|
||||
# The target selector is always optional. The format is one of:
|
||||
#
|
||||
# { xfail *-*-* ... } - the test is expected to fail for the given targets
|
||||
# { target *-*-* ... } - the option only applies to the given targets
|
||||
#
|
||||
# At least one target must be specified, use *-*-* for "all targets".
|
||||
# At present it is not possible to specify both `xfail' and `target'.
|
||||
# "native" may be used in place of "*-*-*".
|
||||
|
||||
Example 1: Testing compilation only
|
||||
// { dg-do compile }
|
||||
|
||||
Example 2: Testing for expected warnings on line 36, which all targets fail
|
||||
// { dg-warning "string literals" "" { xfail *-*-* } 36
|
||||
|
||||
Example 3: Testing for expected warnings on line 36
|
||||
// { dg-warning "string literals" "" { target *-*-* } 36
|
||||
|
||||
Example 4: Testing for compilation errors on line 41
|
||||
// { dg-do compile }
|
||||
// { dg-error "no match for" "" { target *-*-* } 41 }
|
||||
|
||||
Example 5: Testing with special command line settings, or without the
|
||||
use of pre-compiled headers, in particular the stdc++.h.gch file. Any
|
||||
options here will override the DEFAULT_CXXFLAGS and PCH_CXXFLAGS set
|
||||
up in the normal.exp file.
|
||||
// { dg-options "-O0" { target *-*-* } }
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
More examples can be found in the libstdc++-v3/testsuite/*/*.cc files.
|
||||
</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="check">Options for running the tests</a></h2>
|
||||
|
||||
<p> There are several options for running tests, including testing
|
||||
the regression tests, testing a subset of the regression tests,
|
||||
testing the performance tests, testing just compilation, testing
|
||||
installed tools, etc. In addition, there is a special rule for
|
||||
checking the exported symbols of the shared library.
|
||||
</p>
|
||||
|
||||
<p>You can check the status of the build without installing it
|
||||
using the dejagnu harness, much like the rest of the gcc tools.</p>
|
||||
<pre> make check</pre>
|
||||
<p>in the <em>libbuilddir</em> directory.</p>
|
||||
<p>or</p>
|
||||
<pre> make check-target-libstdc++-v3</pre>
|
||||
<p>in the <em>gccbuilddir</em> directory.</p>
|
||||
|
||||
<p>
|
||||
These commands are functionally equivalent and will create a
|
||||
'testsuite' directory underneath <em>libbuilddir</em> containing
|
||||
the results of the tests. Two results files will be generated:
|
||||
<em> libstdc++.sum</em>, which is a PASS/FAIL summary for each
|
||||
test, and <em>libstdc++.log</em> which is a log of the exact
|
||||
command line passed to the compiler, the compiler output, and
|
||||
the executable output (if any).
|
||||
</p>
|
||||
|
||||
|
||||
<p>
|
||||
To debug the dejagnu test harness during runs, try invoking with a
|
||||
specific argument to the variable RUNTESTFLAGS, as below.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
make check-target-libstdc++-v3 RUNTESTFLAGS="-v"
|
||||
</pre>
|
||||
or
|
||||
<pre>
|
||||
make check-target-libstdc++-v3 RUNTESTFLAGS="-v -v"
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
To run a subset of the library tests, you will need to generate the
|
||||
<em>testsuite_files</em> file by running <tt>make testsuite_files</tt>
|
||||
in the <em>libbuilddir/testsuite</em> directory, described below.
|
||||
Edit the file to remove the tests you don't want and then run the
|
||||
testsuite as normal.
|
||||
</p>
|
||||
|
||||
|
||||
<p>
|
||||
There are two ways to run on a simulator: set up DEJAGNU to point to a
|
||||
specially crafted site.exp, or pass down --target_board flags.
|
||||
</p>
|
||||
Example flags to pass down for various embedded builds are as follows:
|
||||
<pre>
|
||||
--target=powerpc-eabism (libgloss/sim)
|
||||
make check-target-libstdc++-v3 RUNTESTFLAGS="--target_board=powerpc-sim"
|
||||
|
||||
--target=calmrisc32 (libgloss/sid)
|
||||
make check-target-libstdc++-v3 RUNTESTFLAGS="--target_board=calmrisc32-sid"
|
||||
|
||||
--target=xscale-elf (newlib/sim)
|
||||
make check-target-libstdc++-v3 RUNTESTFLAGS="--target_board=arm-sim"
|
||||
</pre>
|
||||
|
||||
<p> Also, here is an example of how to run the libstdc++ testsuite for a
|
||||
multilibed build directory with different ABI settings:
|
||||
</p>
|
||||
<pre>
|
||||
make check-target-libstdc++-v3 RUNTESTFLAGS='--target_board \"unix{-mabi=32,,-mabi=64}\"'
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
You can run the tests with a compiler and library that have already
|
||||
been installed. Make sure that the compiler (e.g., <code>g++</code>)
|
||||
is in your <code>PATH</code>. If you are using shared libraries, then
|
||||
you must also ensure that the directory containing the shared version
|
||||
of libstdc++ is in your <code>LD_LIBRARY_PATH</code>, or equivalent.
|
||||
If your GCC source tree is at <code>/path/to/gcc</code>, then you can
|
||||
run the tests as follows:
|
||||
</p>
|
||||
<pre>
|
||||
runtest --tool libstdc++ --srcdir=/path/to/gcc/libstdc++-v3/testsuite
|
||||
</pre>
|
||||
<p>
|
||||
The testsuite will create a number of files in the directory in which you
|
||||
run this command,. Some of those files might use the same name as
|
||||
files created by other testsuites (like the ones for GCC and G++), so
|
||||
you should not try to run all the testsuites in parallel from the same
|
||||
directory.
|
||||
</p>
|
||||
|
||||
<p> In addition, there are some testing options that are mostly of
|
||||
interest to library maintainers and system integrators. As such,
|
||||
these tests may not work on all cpu and host combinations, and may need to
|
||||
be executed in the <em>libbuilddir/testsuite</em> directory. These options
|
||||
include, but are not necessarily limited to, the following:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
make testsuite_files</pre>
|
||||
<p>
|
||||
Five files are generated that determine what test files
|
||||
are run. These files are:
|
||||
</p>
|
||||
<ul>
|
||||
<li>
|
||||
<em>testsuite_files </em>
|
||||
<p> This is a list of all the test cases that will be run. Each
|
||||
test case is on a separate line, given with an absolute path
|
||||
from the <em>libsrcdir/testsuite</em> directory.
|
||||
</p>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<em>testsuite_files_interactive </em>
|
||||
<p> This is a list of all the interactive test cases, using the
|
||||
same format as the file list above. These tests are not run by default.
|
||||
</p>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<em>testsuite_files_performance</em>
|
||||
<p> This is a list of all the performance test cases, using the
|
||||
same format as the file list above. These tests are not run by default.
|
||||
</p>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<em>testsuite_thread</em>
|
||||
<p> This file indicates that the host system can run tests which
|
||||
incolved multiple threads.
|
||||
</p>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<em>testsuite_wchar_t</em>
|
||||
<p> This file indicates that the host system can run the wchar_t
|
||||
tests, and corresponds to the macro definition <code>
|
||||
_GLIBCXX_USE_WCHAR_T</code> in the file c++config.h.
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<pre>
|
||||
make check-abi</pre>
|
||||
<p>The library ABI can be tested. This involves testing the shared
|
||||
library against an ABI-defining previous version of symbol exports. </p>
|
||||
|
||||
<pre>
|
||||
make check-compile</pre>
|
||||
<p>This rule compiles, but does not link or execute, the
|
||||
<em>testsuite_files</em> test cases and displays the output on stdout.</p>
|
||||
|
||||
<pre>
|
||||
make check-performance</pre>
|
||||
<p>This rule runs through the <em>testsuite_files_performance</em>
|
||||
test cases and collects information for performance analysis and
|
||||
can be used to spot performance regressions. Various timing
|
||||
information is collected, as well as number of hard page faults,
|
||||
and memory used. This is not run by default, and the implementation
|
||||
is in flux.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
We are interested in any strange failures of the
|
||||
testsuite; please see <a href="faq/index.html#2_4">FAQ 2.4</a>
|
||||
for which files to examine.
|
||||
</p>
|
||||
|
||||
<hr/>
|
||||
<h2><a name="debug">Running debug-mode tests</a></h2>
|
||||
<p>To run the libstdc++ test suite under the <a
|
||||
href="debug.html#safe">debug mode</a>,
|
||||
edit <code>libstdc++-v3/scripts/testsuite_flags</code> to add the
|
||||
compile-time flag <code>-D_GLIBCXX_DEBUG</code> to the result
|
||||
printed by the <code>--build-cxx</code> option. Additionally, add
|
||||
the <code>-D_GLIBCXX_DEBUG_PEDANTIC</code> flag to turn on pedantic
|
||||
checking. The libstdc++ test suite should produce precisely the same
|
||||
results under debug mode that it does under release mode: any
|
||||
deviation indicates an error in either the library or the test
|
||||
suite.</p>
|
||||
|
||||
<hr />
|
||||
<h2><a name="future">Future</a></h2>
|
||||
|
||||
<p>
|
||||
Shared runs need to be implemented, for targets that support shared libraries.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Diffing of expected output to standard streams needs to be finished off.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The V3 testing framework supports, or will eventually support,
|
||||
additional keywords for the purpose of easing the job of writing
|
||||
test cases. All V3-keywords are of the form <code>@xxx@</code>.
|
||||
Currently plans for supported keywords include:
|
||||
</p>
|
||||
|
||||
<dl>
|
||||
<dt> <code> @require@ <files> </code> </dt>
|
||||
<dd>
|
||||
<p>
|
||||
The existence of <files> is essential for the test to complete
|
||||
successfully. For example, a test case foo.C using bar.baz as
|
||||
input file could say
|
||||
</p>
|
||||
<pre>
|
||||
// @require@ bar.baz</pre>
|
||||
<p>
|
||||
The special variable % stands for the rootname, e.g. the
|
||||
file-name without its `.C' extension. Example of use (taken
|
||||
verbatim from 27_io/filebuf.cc)
|
||||
</p>
|
||||
<pre>
|
||||
// @require@ %-*.tst %-*.txt</pre>
|
||||
</dd>
|
||||
<dt> <code> @diff@ <first-list> <second-list> </code> </dt>
|
||||
<dd>
|
||||
<p>
|
||||
After the test case compiles and ran successfully, diff
|
||||
<first-list> against <second-list>, these lists should
|
||||
have the same length. The test fails if diff returns non-zero a
|
||||
pair of files.
|
||||
</p>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
<hr />
|
||||
<h2><a name="internals">DejaGNU internals</a></h2>
|
||||
|
||||
<p>This is information for those looking at making changes to the testsuite
|
||||
structure, and/or needing to trace dejagnu's actions with --verbose. This
|
||||
will not be useful to people who are "merely" adding new tests to the existing
|
||||
structure.
|
||||
</p>
|
||||
|
||||
<p>The first key point when working with dejagnu is the idea of a "tool".
|
||||
Files, directories, and functions are all implicitly used when they are
|
||||
named after the tool in use. Here, the tool will always be "libstdc++".
|
||||
</p>
|
||||
|
||||
<p>The <code>lib</code> subdir contains support routines. The
|
||||
<code>lib/libstdc++.exp</code> file ("support library") is loaded
|
||||
automagically, and must explicitly load the others. For example, files can
|
||||
be copied from the core compiler's support directory into <code>lib</code>.
|
||||
</p>
|
||||
|
||||
<p>Some routines in <code>lib/libstdc++.exp</code> are callbacks, some are
|
||||
our own. Callbacks must be prefixed with the name of the tool. To easily
|
||||
distinguish the others, by convention our own routines are named "v3-*".
|
||||
</p>
|
||||
|
||||
<p>The next key point when working with dejagnu is "test files". Any
|
||||
directory whose name starts with the tool name will be searched for test files.
|
||||
(We have only one.) In those directories, any <code>.exp</code> file is
|
||||
considered a test file, and will be run in turn. Our main test file is called
|
||||
<code>normal.exp</code>; it runs all the tests in testsuite_files using the
|
||||
callbacks loaded from the support library.
|
||||
</p>
|
||||
|
||||
<p>The <code>config</code> directory is searched for any particular "target
|
||||
board" information unique to this library. This is currently unused and sets
|
||||
only default variables.
|
||||
</p>
|
||||
|
||||
|
||||
<!-- ####################################################### -->
|
||||
|
||||
<hr />
|
||||
<p class="fineprint"><em>
|
||||
See <a href="17_intro/license.html">license.html</a> for copying conditions.
|
||||
Comments and suggestions are welcome, and may be sent to
|
||||
<a href="mailto:libstdc++@gcc.gnu.org">the libstdc++ mailing list</a>.
|
||||
</em></p>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
Loading…
Add table
Reference in a new issue