<?xml version='1.0'?><!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN""http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd"[ ]><chapter id="manual.ext.debug_mode" xreflabel="Debug Mode"><?dbhtml filename="debug_mode.html"?><chapterinfo><keywordset><keyword>C++</keyword><keyword>library</keyword><keyword>debug</keyword></keywordset></chapterinfo><title>Debug Mode</title><sect1 id="manual.ext.debug_mode.intro" xreflabel="Intro"><title>Intro</title><para>By default, libstdc++ is built with efficiency in mind, andtherefore performs little or no error checking that is notrequired by the C++ standard. This means that programs thatincorrectly use the C++ standard library will exhibit behaviorthat is not portable and may not even be predictable, because theytread into implementation-specific or undefined behavior. Todetect some of these errors before they can become problematic,libstdc++ offers a debug mode that provides additional checking oflibrary facilities, and will report errors in the use of libstdc++as soon as they can be detected by emitting a description of theproblem to standard error and aborting the program. This debugmode is available with GCC 3.4.0 and later versions.</para><para>The libstdc++ debug mode performs checking for many areas of theC++ standard, but the focus is on checking interactions amongstandard iterators, containers, and algorithms, including:</para><itemizedlist><listitem><para><emphasis>Safe iterators</emphasis>: Iterators keep track of thecontainer whose elements they reference, so errors such asincrementing a past-the-end iterator or dereferencing an iteratorthat points to a container that has been destructed are diagnosedimmediately.</para></listitem><listitem><para><emphasis>Algorithm preconditions</emphasis>: Algorithms attempt tovalidate their input parameters to detect errors as early aspossible. For instance, the <code>set_intersection</code>algorithm requires that its iteratorparameters <code>first1</code> and <code>last1</code> form a validiterator range, and that the sequence[<code>first1</code>, <code>last1</code>) is sorted according tothe same predicate that was passedto <code>set_intersection</code>; the libstdc++ debug mode willdetect an error if the sequence is not sorted or was sorted by adifferent predicate.</para></listitem></itemizedlist></sect1><sect1 id="manual.ext.debug_mode.semantics" xreflabel="Semantics"><title>Semantics</title><para></para><para>A program that uses the C++ standard library correctlywill maintain the same semantics under debug mode as it had withthe normal (release) library. All functional and exception-handlingguarantees made by the normal library also hold for the debug modelibrary, with one exception: performance guarantees made by thenormal library may not hold in the debug mode library. Forinstance, erasing an element in a <code>std::list</code> is aconstant-time operation in normal library, but in debug mode it islinear in the number of iterators that reference that particularlist. So while your (correct) program won't change its results, itis likely to execute more slowly.</para><para>libstdc++ includes many extensions to the C++ standard library. Insome cases the extensions are obvious, such as the hashedassociative containers, whereas other extensions give predictableresults to behavior that would otherwise be undefined, such asthrowing an exception when a <code>std::basic_string</code> isconstructed from a NULL character pointer. This latter category alsoincludes implementation-defined and unspecified semantics, such asthe growth rate of a vector. Use of these extensions is notconsidered incorrect, so code that relies on them will not berejected by debug mode. However, use of these extensions may affectthe portability of code to other implementations of the C++ standardlibrary, and is therefore somewhat hazardous. For this reason, thelibstdc++ debug mode offers a "pedantic" mode (similar toGCC's <code>-pedantic</code> compiler flag) that attempts to emulatethe semantics guaranteed by the C++ standard. Forinstance, constructing a <code>std::basic_string</code> with a NULLcharacter pointer would result in an exception under normal mode ornon-pedantic debug mode (this is a libstdc++ extension), whereasunder pedantic debug mode libstdc++ would signal an error. To enablethe pedantic debug mode, compile your program withboth <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 hasbeen fixed in GCC 4.0.1 and later versions.) </para><para>The following library components provide extra debuggingcapabilities in debug mode:</para><itemizedlist><listitem><para><code>std::basic_string</code> (no safe iterators and see note below)</para></listitem><listitem><para><code>std::bitset</code></para></listitem><listitem><para><code>std::deque</code></para></listitem><listitem><para><code>std::list</code></para></listitem><listitem><para><code>std::map</code></para></listitem><listitem><para><code>std::multimap</code></para></listitem><listitem><para><code>std::multiset</code></para></listitem><listitem><para><code>std::set</code></para></listitem><listitem><para><code>std::vector</code></para></listitem><listitem><para><code>std::unordered_map</code></para></listitem><listitem><para><code>std::unordered_multimap</code></para></listitem><listitem><para><code>std::unordered_set</code></para></listitem><listitem><para><code>std::unordered_multiset</code></para></listitem></itemizedlist><para>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 instantiationsof <code>std::string</code> and <code>std::wstring</code>, and thoseexplicit instantiations don't include the debug-mode checks. If thecontaining functions are inlined then the checks will run, so compilingwith <code>-O1</code> might be enough to enable them. Alternatively<code>-D_GLIBCXX_EXTERN_TEMPLATE=0</code> will suppress the declarationsof the explicit instantiations and cause the functions to be instantiatedwith the debug-mode checks included, but this is unsupported and notguaranteed to work. For full debug-mode support you can use the<code>__gnu_debug::basic_string</code> debugging container directly,which always works correctly.</para></sect1><sect1 id="manual.ext.debug_mode.using" xreflabel="Using"><title>Using</title><para></para><sect2 id="debug_mode.using.mode" xreflabel="Using Mode"><title>Using the Debug Mode</title><para>To use the libstdc++ debug mode, compile your application with thecompiler flag <code>-D_GLIBCXX_DEBUG</code>. Note that this flagchanges the sizes and behavior of standard class templates suchas <code>std::vector</code>, and therefore you can only link codecompiled with debug mode and code compiled without debug mode if noinstantiation of a container is passed between the two translationunits.</para><para>By default, error messages are formatted to fit on lines of about78 characters. The environment variable<code>GLIBCXX_DEBUG_MESSAGE_LENGTH</code> can be used to request adifferent length.</para></sect2><sect2 id="debug_mode.using.specific" xreflabel="Using Specific"><title>Using a Specific Debug Container</title><para>When it is not feasible to recompile your entire application, oronly specific containers need checking, debugging containers areavailable as GNU extensions. These debugging containers arefunctionally equivalent to the standard drop-in containers used indebug mode, but they are available in a separate namespace as GNUextensions and may be used in programs compiled with either releasemode or with debug mode. Thefollowing table provides the names and headers of the debuggingcontainers:</para><table frame='all'><title>Debugging Containers</title><tgroup cols='6' align='left' colsep='1' rowsep='1'><colspec colname='c1'></colspec><colspec colname='c2'></colspec><colspec colname='c3'></colspec><colspec colname='c4'></colspec><thead><row><entry>Container</entry><entry>Header</entry><entry>Debug container</entry><entry>Debug header</entry></row></thead><tbody><row><entry><classname>std::bitset</classname></entry><entry><filename class="headerfile">bitset</filename></entry><entry><classname>__gnu_debug::bitset</classname></entry><entry><filename class="headerfile">bitset</filename></entry></row><row><entry><classname>std::deque</classname></entry><entry><filename class="headerfile">deque</filename></entry><entry><classname>__gnu_debug::deque</classname></entry><entry><filename class="headerfile">deque</filename></entry></row><row><entry><classname>std::list</classname></entry><entry><filename class="headerfile">list</filename></entry><entry><classname>__gnu_debug::list</classname></entry><entry><filename class="headerfile">list</filename></entry></row><row><entry><classname>std::map</classname></entry><entry><filename class="headerfile">map</filename></entry><entry><classname>__gnu_debug::map</classname></entry><entry><filename class="headerfile">map</filename></entry></row><row><entry><classname>std::multimap</classname></entry><entry><filename class="headerfile">map</filename></entry><entry><classname>__gnu_debug::multimap</classname></entry><entry><filename class="headerfile">map</filename></entry></row><row><entry><classname>std::multiset</classname></entry><entry><filename class="headerfile">set</filename></entry><entry><classname>__gnu_debug::multiset</classname></entry><entry><filename class="headerfile">set</filename></entry></row><row><entry><classname>std::set</classname></entry><entry><filename class="headerfile">set</filename></entry><entry><classname>__gnu_debug::set</classname></entry><entry><filename class="headerfile">set</filename></entry></row><row><entry><classname>std::string</classname></entry><entry><filename class="headerfile">string</filename></entry><entry><classname>__gnu_debug::string</classname></entry><entry><filename class="headerfile">string</filename></entry></row><row><entry><classname>std::wstring</classname></entry><entry><filename class="headerfile">string</filename></entry><entry><classname>__gnu_debug::wstring</classname></entry><entry><filename class="headerfile">string</filename></entry></row><row><entry><classname>std::basic_string</classname></entry><entry><filename class="headerfile">string</filename></entry><entry><classname>__gnu_debug::basic_string</classname></entry><entry><filename class="headerfile">string</filename></entry></row><row><entry><classname>std::vector</classname></entry><entry><filename class="headerfile">vector</filename></entry><entry><classname>__gnu_debug::vector</classname></entry><entry><filename class="headerfile">vector</filename></entry></row></tbody></tgroup></table><para>In addition, when compiling in C++0x mode, these additionalcontainers have additional debug capability.</para><table frame='all'><title>Debugging Containers C++0x</title><tgroup cols='6' align='left' colsep='1' rowsep='1'><colspec colname='c1'></colspec><colspec colname='c2'></colspec><colspec colname='c3'></colspec><colspec colname='c4'></colspec><thead><row><entry>Container</entry><entry>Header</entry><entry>Debug container</entry><entry>Debug header</entry></row></thead><tbody><row><entry><classname>std::unordered_map</classname></entry><entry><filename class="headerfile">unordered_map</filename></entry><entry><classname>__gnu_debug::unordered_map</classname></entry><entry><filename class="headerfile">unordered_map</filename></entry></row><row><entry><classname>std::unordered_multimap</classname></entry><entry><filename class="headerfile">unordered_map</filename></entry><entry><classname>__gnu_debug::unordered_multimap</classname></entry><entry><filename class="headerfile">unordered_map</filename></entry></row><row><entry><classname>std::unordered_set</classname></entry><entry><filename class="headerfile">unordered_set</filename></entry><entry><classname>__gnu_debug::unordered_set</classname></entry><entry><filename class="headerfile">unordered_set</filename></entry></row><row><entry><classname>std::unordered_multiset</classname></entry><entry><filename class="headerfile">unordered_set</filename></entry><entry><classname>__gnu_debug::unordered_multiset</classname></entry><entry><filename class="headerfile">unordered_set</filename></entry></row></tbody></tgroup></table></sect2></sect1><sect1 id="manual.ext.debug_mode.design" xreflabel="Design"><title>Design</title><para></para><sect2 id="manual.ext.debug_mode.design.goals" xreflabel="Goals"><title>Goals</title><para></para><para> The libstdc++ debug mode replaces unsafe (but efficient) standardcontainers and iterators with semantically equivalent safe standardcontainers and iterators to aid in debugging user programs. Thefollowing goals directed the design of the libstdc++ debug mode:</para><itemizedlist><listitem><para><emphasis>Correctness</emphasis>: the libstdc++ debug mode must not changethe semantics of the standard library for all cases specified inthe ANSI/ISO C++ standard. The essence of this constraint is thatany valid C++ program should behave in the same manner regardlessof whether it is compiled with debug mode or release mode. Inparticular, entities that are defined in namespace std in releasemode should remain defined in namespace std in debug mode, so thatlegal specializations of namespace std entities will remainvalid. A program that is not valid C++ (e.g., invokes undefinedbehavior) is not required to behave similarly, although the debugmode will abort with a diagnostic when it detects undefinedbehavior.</para></listitem><listitem><para><emphasis>Performance</emphasis>: the additional of the libstdc++ debug modemust not affect the performance of the library when it is compiledin release mode. Performance of the libstdc++ debug mode issecondary (and, in fact, will be worse than the releasemode).</para></listitem><listitem><para><emphasis>Usability</emphasis>: the libstdc++ debug mode should be easy touse. It should be easily incorporated into the user's developmentenvironment (e.g., by requiring only a single new compiler switch)and should produce reasonable diagnostics when it detects aproblem with the user program. Usability also involves detectionof errors when using the debug mode incorrectly, e.g., by linkinga release-compiled object against a debug-compiled object if infact the resulting program will not run correctly.</para></listitem><listitem><para><emphasis>Minimize recompilation</emphasis>: While it is expected thatusers recompile at least part of their program to use debugmode, the amount of recompilation affects thedetect-compile-debug turnaround time. This indirectly affects theusefulness of the debug mode, because debugging some applicationsmay require rebuilding a large amount of code, which may not befeasible when the suspect code may be very localized. There areseveral levels of conformance to this requirement, each with itsown usability and implementation characteristics. In general, thehigher-numbered conformance levels are more usable (i.e., requireless recompilation) but are more complicated to implement thanthe lower-numbered conformance levels.<orderedlist><listitem><para><emphasis>Full recompilation</emphasis>: The user must recompile his orher entire application and all C++ libraries it depends on,including the C++ standard library that ships with thecompiler. This must be done even if only a small part of theprogram can use debugging features.</para></listitem><listitem><para><emphasis>Full user recompilation</emphasis>: The user must recompilehis or her entire application and all C++ libraries it dependson, but not the C++ standard library itself. This must be doneeven if only a small part of the program can use debuggingfeatures. This can be achieved given a full recompilationsystem by compiling two versions of the standard library whenthe compiler is installed and linking against the appropriateone, e.g., a multilibs approach.</para></listitem><listitem><para><emphasis>Partial recompilation</emphasis>: The user must recompile theparts of his or her application and the C++ libraries itdepends on that will use the debugging facilitiesdirectly. This means that any code that uses the debuggablestandard containers would need to be recompiled, but codethat does not use them (but may, for instance, use IOStreams)would not have to be recompiled.</para></listitem><listitem><para><emphasis>Per-use recompilation</emphasis>: The user must recompile theparts of his or her application and the C++ libraries itdepends on where debugging should occur, and any other codethat interacts with those containers. This means that a set oftranslation units that accesses a particular standardcontainer instance may either be compiled in release mode (nochecking) or debug mode (full checking), but must all becompiled in the same way; a translation unit that does not seethat standard container instance need not be recompiled. Thisalso means that a translation unit <emphasis>A</emphasis> that contains aparticular instantiation(say, <code>std::vector<int></code>) compiled in releasemode can be linked against a translation unit <emphasis>B</emphasis> thatcontains the same instantiation compiled in debug mode (afeature not present with partial recompilation). While thisbehavior is technically a violation of the One DefinitionRule, this ability tends to be very important inpractice. The libstdc++ debug mode supports this level ofrecompilation. </para></listitem><listitem><para><emphasis>Per-unit recompilation</emphasis>: The user must onlyrecompile the translation units where checking should occur,regardless of where debuggable standard containers areused. 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-unitgranularity. We believe that this level of recompilation is infact not possible if we intend to supply safe iterators, leavethe program semantics unchanged, and not regress inperformance under release mode because we cannot associateextra information with an iterator (to form a safe iterator)without either reserving that space in release mode(performance regression) or allocating extra memory associatedwith each iterator with <code>new</code> (changes the programsemantics).</para></listitem></orderedlist></para></listitem></itemizedlist></sect2><sect2 id="manual.ext.debug_mode.design.methods" xreflabel="Methods"><title>Methods</title><para></para><para>This section provides an overall view of the design of thelibstdc++ debug mode and details the relationship between designdecisions and the stated design goals.</para><sect3 id="debug_mode.design.methods.wrappers" xreflabel="Method Wrapper"><title>The Wrapper Model</title><para>The libstdc++ debug mode uses a wrapper model where the debuggingversions of library components (e.g., iterators and containers) forma layer on top of the release versions of the librarycomponents. The debugging components first verify that the operationis correct (aborting with a diagnostic if an error is found) andwill then forward to the underlying release-mode container that willperform the actual work. This design decision ensures that we cannotregress release-mode performance (because the release-modecontainers are left untouched) and partially enables <ulink url="#mixing">mixing debug and release code</ulink> at link time,although that will not be discussed at this time.</para><para>Two types of wrappers are used in the implementation of the debugmode: container wrappers and iterator wrappers. The two types ofwrappers interact to maintain relationships between iterators andtheir associated containers, which are necessary to detect certaintypes of standard library usage errors such as dereferencingpast-the-end iterators or inserting into a container using aniterator from a different container.</para><sect4 id="debug_mode.design.methods.safe_iter" xreflabel="Method Safe Iter"><title>Safe Iterators</title><para>Iterator wrappers provide a debugging layer over any iterator thatis attached to a particular container, and will manage theinformation detailing the iterator's state (singular,dereferenceable, etc.) and tracking the container to which theiterator is attached. Because iterators have a well-defined, commoninterface the iterator wrapper is implemented with the iteratoradaptor class template <code>__gnu_debug::_Safe_iterator</code>,which takes two template parameters:</para><itemizedlist><listitem><para><code>Iterator</code>: The underlying iterator type, which mustbe either the <code>iterator</code> or <code>const_iterator</code>typedef from the sequence type this iterator can reference.</para></listitem><listitem><para><code>Sequence</code>: The type of sequence that this iteratorreferences. This sequence must be a safe sequence (discussed below)whose <code>iterator</code> or <code>const_iterator</code> typedefis the type of the safe iterator.</para></listitem></itemizedlist></sect4><sect4 id="debug_mode.design.methods.safe_seq" xreflabel="Method Safe Seq"><title>Safe Sequences (Containers)</title><para>Container wrappers provide a debugging layer over a particularcontainer type. Because containers vary greatly in the memberfunctions they support and the semantics of those member functions(especially in the area of iterator invalidation), containerwrappers are tailored to the container they reference, e.g., thedebugging version of <code>std::list</code> duplicates the entireinterface of <code>std::list</code>, adding additional semanticchecks and then forwarding operations to thereal <code>std::list</code> (a public base class of the debuggingversion) as appropriate. However, all safe containers inherit fromthe class template <code>__gnu_debug::_Safe_sequence</code>,instantiated with the type of the safe container itself (an instanceof the curiously recurring template pattern).</para><para>The iterators of a container wrapper will be<ulink url="#safe_iterator">safe iterators</ulink> that reference sequencesof this type and wrap the iterators provided by the release-modebase class. The debugging container will use only the safeiterators within its own interface (therefore requiring the user touse safe iterators, although this does not change correct usercode) and will communicate with the release-mode base class withonly the underlying, unsafe, release-mode iterators that the baseclass exports.</para><para> The debugging version of <code>std::list</code> will have thefollowing basic structure:</para><programlisting>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};</programlisting></sect4></sect3><sect3 id="debug_mode.design.methods.precond" xreflabel="Precondition check"><title>Precondition Checking</title><para>The debug mode operates primarily by checking the preconditions ofall standard library operations that it supports. Preconditions thatare always checked (regardless of whether or not we are in debugmode) are checked via the <code>__check_xxx</code> macros definedand documented in the sourcefile <code>include/debug/debug.h</code>. Preconditions that may ormay not be checked, depending on the debug-modemacro <code>_GLIBCXX_DEBUG</code>, are checked viathe <code>__requires_xxx</code> macros defined and documented in thesame source file. Preconditions are validated using any additionalinformation available at run-time, e.g., the containers that areassociated with a particular iterator, the position of the iteratorwithin those containers, the distance between two iterators that mayform a valid range, etc. In the absence of suitable information,e.g., an input iterator that is not a safe iterator, theseprecondition checks will silently succeed.</para><para>The majority of precondition checks use the aforementioned macros,which have the secondary benefit of having prewritten debugmessages that use information about the current status of theobjects involved (e.g., whether an iterator is singular or whatsequence it is attached to) along with some static information(e.g., the names of the function parameters corresponding to theobjects involved). When not using these macros, the debug mode useseither the debug-mode assertionmacro <code>_GLIBCXX_DEBUG_ASSERT</code> , its pedanticcousin <code>_GLIBCXX_DEBUG_PEDASSERT</code>, or the assertioncheck macro that supports more advance formulation of errormessages, <code>_GLIBCXX_DEBUG_VERIFY</code>. These macros aredocumented more thoroughly in the debug mode source code.</para></sect3><sect3 id="debug_mode.design.methods.coexistence" xreflabel="Coexistence"><title>Release- and debug-mode coexistence</title><para>The libstdc++ debug mode is the first debug mode we know of thatis able to provide the "Per-use recompilation" (4) guarantee, thatallows release-compiled and debug-compiled code to be linked andexecuted together without causing unpredictable behavior. Thisguarantee minimizes the recompilation that users are required toperform, shortening the detect-compile-debug bug hunting cycleand making the debug mode easier to incorporate into developmentenvironments by minimizing dependencies.</para><para>Achieving link- and run-time coexistence is not a trivialimplementation task. To achieve this goal we required a smallextension to the GNU C++ compiler (described in the GCC Manual forC++ Extensions, see <ulink url="http://gcc.gnu.org/onlinedocs/gcc/Strong-Using.html">strongusing</ulink>), and a complex organization of debug- andrelease-modes. The end result is that we have achieved per-userecompilation but have had to give up some checking of the<code>std::basic_string</code> class template (namely, safeiterators).</para><sect4 id="methods.coexistence.compile" xreflabel="Compile"><title>Compile-time coexistence of release- and debug-mode components</title><para>Both the release-mode components and the debug-modecomponents need to exist within a single translation unit so thatthe debug versions can wrap the release versions. However, only oneof these components should be user-visible at any particulartime with the standard name, e.g., <code>std::list</code>. </para><para>In release mode, we define only the release-mode version of thecomponent with its standard name and do not include the debuggingcomponent at all. The release mode version is defined within thenamespace <code>std</code>. Minus the namespace associations, thismethod leaves the behavior of release mode completely unchanged fromits behavior prior to the introduction of the libstdc++ debugmode. Here's an example of what this ends up looking like, inC++.</para><programlisting>namespace std{template<typename _Tp, typename _Alloc = allocator<_Tp> >class list{// ...};} // namespace std</programlisting><para>In debug mode we include the release-mode container (which is nowdefined in in the namespace <code>__norm</code>) and also thedebug-mode container. The debug-mode container is defined within thenamespace <code>__debug</code>, which is associated with namespace<code>std</code> via the GNU namespace association extension. Thismethod allows the debug and release versions of the same component tocoexist at compile-time and link-time without causing an unreasonablemaintenance burden, while minimizing confusion. Again, this boils downto C++ code as follows:</para><programlisting>namespace std{namespace __norm{template<typename _Tp, typename _Alloc = allocator<_Tp> >class list{// ...};} // namespace __gnu_normnamespace __debug{template<typename _Tp, typename _Alloc = allocator<_Tp> >class list: public __norm::list<_Tp, _Alloc>,public __gnu_debug::_Safe_sequence<list<_Tp, _Alloc> >{// ...};} // namespace __normusing namespace __debug __attribute__ ((strong));}</programlisting></sect4><sect4 id="methods.coexistence.link" xreflabel="Link"><title>Link- and run-time coexistence of release- anddebug-mode components</title><para>Because each component has a distinct and separate release anddebug implementation, there are are no issues with link-timecoexistence: the separate namespaces result in different manglednames, and thus unique linkage.</para><para>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, butwith a mixed mode standard library that could be using eitherdebug-mode or release-mode <code> basic_string</code> objects, thingsget more complicated. As the return value of a function is notencoded into the mangled name, there is no way to specify arelease-mode or a debug-mode string. In practice, this results inruntime errors. A simplified example of this problem is as follows.</para><para> Take this translation unit, compiled in debug-mode: </para><programlisting>// -D_GLIBCXX_DEBUG#include <string>std::string test02();std::string test01(){return test02();}int main(){test01();return 0;}</programlisting><para> ... and linked to this translation unit, compiled in release mode:</para><programlisting>#include <string>std::stringtest02(){return std::string("toast");}</programlisting><para> For this reason we cannot easily provide safe iterators forthe <code>std::basic_string</code> class template, as it is presentthroughout the C++ standard library. For instance, locale facetsdefine typedefs that include <code>basic_string</code>: in a mixeddebug/release program, should that typedef be based on thedebug-mode <code>basic_string</code> or therelease-mode <code>basic_string</code>? While the answer could be"both", and the difference hidden via renaming a la thedebug/release containers, we must note two things about localefacets:</para><orderedlist><listitem><para>They exist as shared state: one can create a facet in onetranslation unit and access the facet via the same type name in adifferent translation unit. This means that we cannot have twodifferent versions of locale facets, because the types would not bethe same across debug/release-mode translation unit barriers.</para></listitem><listitem><para>They have virtual functions returning strings: these functionsmangle in the same way regardless of the mangling of their returntypes (see above), and their precise signatures can be relied uponby users because they may be overridden in derived classes.</para></listitem></orderedlist><para>With the design of libstdc++ debug mode, we cannot effectively hidethe differences between debug and release-mode strings from theuser. Failure to hide the differences may result in unpredictablebehavior, and for this reason we have opted to onlyperform <code>basic_string</code> changes that do not require ABIchanges. The effect on users is expected to be minimal, as there aresimple alternatives (e.g., <code>__gnu_debug::basic_string</code>),and the usability benefit we gain from the ability to mix debug- andrelease-compiled translation units is enormous.</para></sect4><sect4 id="methods.coexistence.alt" xreflabel="Alternatives"><title>Alternatives for Coexistence</title><para>The coexistence scheme above was chosen over many alternatives,including language-only solutions and solutions that also requiredextensions to the C++ front end. The following is a partial list ofsolutions, with justifications for our rejection of each.</para><itemizedlist><listitem><para><emphasis>Completely separate debug/release libraries</emphasis>: This is byfar the simplest implementation option, where we do not allow anycoexistence of debug- and release-compiled translation units in aprogram. This solution has an extreme negative affect on usability,because it is quite likely that some libraries an applicationdepends on cannot be recompiled easily. This would not meetour <emphasis>usability</emphasis> or <emphasis>minimize recompilation</emphasis> criteriawell.</para></listitem><listitem><para><emphasis>Add a <code>Debug</code> boolean template parameter</emphasis>:Partial specialization could be used to select the debugimplementation when <code>Debug == true</code>, and the stateof <code>_GLIBCXX_DEBUG</code> could decide whether thedefault <code>Debug</code> argument is <code>true</code>or <code>false</code>. This option would break conformance with theC++ standard in both debug <emphasis>and</emphasis> release modes. This wouldnot meet our <emphasis>correctness</emphasis> criteria. </para></listitem><listitem><para><emphasis>Packaging a debug flag in the allocators</emphasis>: We couldreuse the <code>Allocator</code> template parameter of containersby adding a sentinel wrapper <code>debug<></code> thatsignals the user's intention to use debugging, and pick upthe <code>debug<></code> allocator wrapper in a partialspecialization. However, this has two drawbacks: first, there is aconformance issue because the default allocator would not be thestandard-specified <code>std::allocator<T></code>. Secondly(and more importantly), users that specify allocators instead ofimplicitly using the default allocator would not get debuggingcontainers. Thus this solution fails the <emphasis>correctness</emphasis>criteria.</para></listitem><listitem><para><emphasis>Define debug containers in another namespace, and employa <code>using</code> declaration (or directive)</emphasis>: This is anenticing option, because it would eliminate the need forthe <code>link_name</code> extension by aliasing thetemplates. However, there is no true template aliasing mechanismis C++, because both <code>using</code> directives and usingdeclarations disallow specialization. This method failsthe <emphasis>correctness</emphasis> criteria.</para></listitem><listitem><para><emphasis> Use implementation-specific properties of anonymousnamespaces. </emphasis>See <ulink url="http://gcc.gnu.org/ml/libstdc++/2003-08/msg00004.html"> this post</ulink>This method fails the <emphasis>correctness</emphasis> criteria.</para></listitem><listitem><para><emphasis>Extension: allow reopening on namespaces</emphasis>: This wouldallow the debug mode to effectively alias thenamespace <code>std</code> to an internal namespace, suchas <code>__gnu_std_debug</code>, so that it is completelyseparate from the release-mode <code>std</code> namespace. Whilethis will solve some renaming problems and ensure thatdebug- and release-compiled code cannot be mixed unsafely, it ensures thatdebug- and release-compiled code cannot be mixed at all. Forinstance, the program would have two <code>std::cout</code>objects! This solution would fails the <emphasis>minimizerecompilation</emphasis> requirement, because we would only be able tosupport option (1) or (2).</para></listitem><listitem><para><emphasis>Extension: use link name</emphasis>: This option involvescomplicated re-naming between debug-mode and release-modecomponents at compile time, and then a g++ extension called <emphasis>link name </emphasis> to recover the original names at link time. Thereare two drawbacks to this approach. One, it's very verbose,relying on macro renaming at compile time and several levels ofinclude ordering. Two, ODR issues remained with container memberfunctions taking no arguments in mixed-mode settings resulting inequivalent link names, <code> vector::push_back() </code> beingone example.See <ulink url="http://gcc.gnu.org/ml/libstdc++/2003-08/msg00177.html">linkname</ulink> </para></listitem></itemizedlist><para>Other options may exist for implementing the debug mode, many ofwhich have probably been considered and others that may still belurking. This list may be expanded over time to include otheroptions that we could have implemented, but in all cases the fullramifications of the approach (as measured against the design goalsfor a libstdc++ debug mode) should be considered first. The DejaGNUtestsuite includes some testcases that check for known problems withsome solutions (e.g., the <code>using</code> declaration solutionthat breaks user specialization), and additional testcases will beadded as we are able to identify other typical problem cases. Thesetest cases will serve as a benchmark by which we can compare debugmode implementations.</para></sect4></sect3></sect2><sect2 id="manual.ext.debug_mode.design.other" xreflabel="Other"><title>Other Implementations</title><para></para><para> There are several existing implementations of debug modes for C++standard library implementations, although none of them directlysupports debugging for programs using libstdc++. The existingimplementations include:</para><itemizedlist><listitem><para><ulink url="http://www.mathcs.sjsu.edu/faculty/horstman/safestl.html">SafeSTL</ulink>:SafeSTL was the original debugging version of the Standard TemplateLibrary (STL), implemented by Cay S. Horstmann on top of theHewlett-Packard STL. Though it inspired much work in this area, ithas not been kept up-to-date for use with modern compilers or C++standard library implementations.</para></listitem><listitem><para><ulink url="http://www.stlport.org/">STLport</ulink>: STLport is a freeimplementation of the C++ standard library derived from the <ulink url="http://www.sgi.com/tech/stl/">SGI implementation</ulink>, andported to many other platforms. It includes a debug mode that uses awrapper model (that in some way inspired the libstdc++ debug modedesign), although at the time of this writing the debug mode issomewhat incomplete and meets only the "Full user recompilation" (2)recompilation guarantee by requiring the user to link against adifferent library in debug mode vs. release mode.</para></listitem><listitem><para><ulink url="http://www.metrowerks.com/mw/default.htm">MetrowerksCodeWarrior</ulink>: The C++ standard library that ships with MetrowerksCodeWarrior includes a debug mode. It is a full debug-modeimplementation (including debugging for CodeWarrior extensions) andis easy to use, although it meets only the "Full recompilation" (1)recompilation guarantee.</para></listitem></itemizedlist></sect2></sect1></chapter>