mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			765 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			HTML
		
	
	
	
			
		
		
	
	
			765 lines
		
	
	
		
			26 KiB
		
	
	
	
		
			HTML
		
	
	
	
| <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
 | |
| <html>
 | |
| <head>
 | |
| <meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type">
 | |
| <title>Libstdc++-porting-howto</title>
 | |
| <meta name="generator" content="DocBook XSL Stylesheets V1.48">
 | |
| </head>
 | |
| <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="article">
 | |
| <div class="titlepage">
 | |
| <div><h1 class="title">
 | |
| <a name="libstdc++-porting-howto"></a>Libstdc++-porting-howto</h1></div>
 | |
| <div><h3 class="author">Felix Natter</h3></div>
 | |
| <div><div class="legalnotice">
 | |
| <p class="legalnotice-title"><b>Legal Notice</b></p>
 | |
| <p>
 | |
| 	This document can be distributed under the FDL
 | |
| 	(<a href="http://www.gnu.org" target="_top">www.gnu.org</a>)
 | |
|       </p>
 | |
| </div></div>
 | |
| <div><p class="pubdate">Tue Jun  5 20:07:49 2001</p></div>
 | |
| <div><div class="revhistory"><table border="1" width="100%" summary="Revision history">
 | |
| <tr><th align="left" valign="top" colspan="3"><b>Revision History</b></th></tr>
 | |
| <tr>
 | |
| <td align="left">Revision 0.5</td>
 | |
| <td align="left">Thu Jun  1 13:06:50 2000</td>
 | |
| <td align="left">fnatter</td>
 | |
| </tr>
 | |
| <tr><td align="left" colspan="3">First docbook-version.</td></tr>
 | |
| <tr>
 | |
| <td align="left">Revision 0.8</td>
 | |
| <td align="left">Sun Jul 30 20:28:40 2000</td>
 | |
| <td align="left">fnatter</td>
 | |
| </tr>
 | |
| <tr><td align="left" colspan="3">First released version using docbook-xml
 | |
| 	  + second upload to libstdc++-page.
 | |
| 	</td></tr>
 | |
| <tr>
 | |
| <td align="left">Revision 0.9</td>
 | |
| <td align="left">Wed Sep  6 02:59:32 2000</td>
 | |
| <td align="left">fnatter</td>
 | |
| </tr>
 | |
| <tr><td align="left" colspan="3">5 new sections.</td></tr>
 | |
| <tr>
 | |
| <td align="left">Revision 0.9.1</td>
 | |
| <td align="left">Sat Sep 23 14:20:15 2000</td>
 | |
| <td align="left">fnatter</td>
 | |
| </tr>
 | |
| <tr><td align="left" colspan="3">added information about why file-descriptors are not in the
 | |
| 	  standard</td></tr>
 | |
| <tr>
 | |
| <td align="left">Revision 0.9.2</td>
 | |
| <td align="left">Tue Jun  5 20:07:49 2001</td>
 | |
| <td align="left">fnatter</td>
 | |
| </tr>
 | |
| <tr><td align="left" colspan="3">
 | |
| 	  a fix, added hint on increased portability of C-shadow-headers,
 | |
| 	  added autoconf-test HAVE_CONTAINER_AT
 | |
| 	</td></tr>
 | |
| <tr>
 | |
| <td align="left">Revision 0.9.3</td>
 | |
| <td align="left">Fri Jun 29 16:15:56 2001</td>
 | |
| <td align="left">fnatter</td>
 | |
| </tr>
 | |
| <tr><td align="left" colspan="3">
 | |
| 	  changed signature of nonstandard filebuf-constructor and
 | |
| 	  update the section on filebuf::attach to point to ../ext/howto.html,
 | |
| 	  added link to ../21/strings/howto.html
 | |
| 	  in sec-stringstream, changed <link>-tags to have content
 | |
| 	  (so that these links work),
 | |
| 	  replace "user-space" by "global namespace"
 | |
| 	  add note about gcc 3.0 and shadow-headers			
 | |
| 	  add section about ostream::form and istream::scan
 | |
| 	  sec-vector-at: remove hint to modify headers
 | |
| 	  fix spelling error in sec-stringstream
 | |
| 	</td></tr>
 | |
| <tr>
 | |
| <td align="left">Revision 0.9.4</td>
 | |
| <td align="left">Mon Nov  5 17:01:04 2001</td>
 | |
| <td align="left">fnatter</td>
 | |
| </tr>
 | |
| <tr><td align="left" colspan="3">
 | |
| 	  rewrite section 1.1.3 because of gnu.gcc.help-post by
 | |
| 	  Juergen Heinzl
 | |
| 	</td></tr>
 | |
| </table></div></div>
 | |
| <div><div class="abstract">
 | |
| <p><b>Abstract</b></p>
 | |
| <p>
 | |
| 	Some notes on porting applications from libstdc++-2.90 (or earlier
 | |
| 	versions) to libstdc++-v3. Not speaking in terms of the GNU libstdc++
 | |
| 	implementations, this means porting from earlier versions of the
 | |
| 	C++-Standard to ISO 14882.
 | |
|       </p>
 | |
| </div></div>
 | |
| <hr>
 | |
| </div>
 | |
| <div class="toc">
 | |
| <p><b>Table of Contents</b></p>
 | |
| <dl>
 | |
| <dt>1. <a href="#sec-nsstd">Namespace std::</a>
 | |
| </dt>
 | |
| <dd><dl>
 | |
| <dt>1.1.1. <a href="#sec-gtkmm-hack">Using namespace
 | |
| 	  composition if the project uses a separate
 | |
| 	namespace</a>
 | |
| </dt>
 | |
| <dt>1.1.2. <a href="#sec-emptyns">Defining an empty namespace std</a>
 | |
| </dt>
 | |
| <dt>1.1.3. <a href="#sec-avoidfqn">Avoid to use fully qualified names
 | |
| 	(i.e. std::string)</a>
 | |
| </dt>
 | |
| <dt>1.1.4. <a href="#sec-osprojects">How some open-source-projects deal
 | |
| 	with this</a>
 | |
| </dt>
 | |
| </dl></dd>
 | |
| <dt>2. <a href="#sec-nocreate">there is no ios::nocreate/ios::noreplace
 | |
|       in ISO 14882</a>
 | |
| </dt>
 | |
| <dt>3. <a href="#sec-stream::attach">stream::attach(int
 | |
| 	fd) is not in the standard any more</a>
 | |
| </dt>
 | |
| <dt>4. <a href="#sec-headers">The new headers</a>
 | |
| </dt>
 | |
| <dd><dl>
 | |
| <dt>4.4.1. <a href="#sec-cheaders">New headers replacing C-headers</a>
 | |
| </dt>
 | |
| <dt>4.4.2. <a href="#sec-fstream-header">
 | |
| 	<fstream> does
 | |
| 	not define std::cout,
 | |
| 	std::cin etc.</a>
 | |
| </dt>
 | |
| </dl></dd>
 | |
| <dt>5. <a href="#sec-iterators">Iterators</a>
 | |
| </dt>
 | |
| <dt>6. <a href="#sec-macros">
 | |
|       Libc-macros (i.e. isspace from
 | |
|       <cctype>)</a>
 | |
| </dt>
 | |
| <dt>7. <a href="#sec-stream-state">State of streams</a>
 | |
| </dt>
 | |
| <dt>8. <a href="#sec-vector-at">vector::at is missing (i.e. gcc 2.95.x)</a>
 | |
| </dt>
 | |
| <dt>9. <a href="#sec-eof">Using std::char_traits<char>::eof()</a>
 | |
| </dt>
 | |
| <dt>10. <a href="#sec-string-clear">Using string::clear()/string::erase()</a>
 | |
| </dt>
 | |
| <dt>11. <a href="#sec-scan-form">GNU Extensions ostream::form and istream::scan</a>
 | |
| </dt>
 | |
| <dt>12. <a href="#sec-stringstream">Using stringstreams</a>
 | |
| </dt>
 | |
| <dt>13. <a href="#sec-about">About...</a>
 | |
| </dt>
 | |
| </dl>
 | |
| </div>
 | |
| <p>
 | |
|     In the following, when I say portable, I will refer to "portable among ISO
 | |
|     14882-implementations". On the other hand, if I say "backportable" or
 | |
|     "conservative", I am talking about "compiles with older
 | |
|     libstdc++-implementations".
 | |
|   </p>
 | |
| <div class="section">
 | |
| <div class="titlepage"><div><h2 class="title" style="clear: both">
 | |
| <a name="sec-nsstd"></a>Namespace std::</h2></div></div>
 | |
| <p>
 | |
|       The latest C++-standard (ISO-14882) requires that the standard
 | |
|       C++-library is defined in namespace std::. Thus, in order to use
 | |
|       classes from the standard C++-library, you can do one of three
 | |
|       things:
 | |
|       <div class="itemizedlist"><ul type="disc">
 | |
| <li><p>wrap your code in <b>namespace std {
 | |
| 	      ... }</b> => This is not an option because only symbols
 | |
| 	    from the standard c++-library are defined in namespace std::.
 | |
| 	  </p></li>
 | |
| <li><p>put a kind of
 | |
| 	    <span class="emphasis"><i>using-declaration</i></span> in your source (either
 | |
| 	    <b>using namespace std;</b> or i.e. <b>using
 | |
| 	      std::string;</b>) => works well for source-files, but
 | |
| 	    cannot be used in header-files.
 | |
| 	  </p></li>
 | |
| <li><p>use a <span class="emphasis"><i>fully qualified name</i></span> for
 | |
| 	    each libstdc++-symbol (i.e. <b>std::string</b>,
 | |
| 	    <b>std::cout</b>) => can always be used
 | |
| 	  </p></li>
 | |
| </ul></div>
 | |
|     </p>
 | |
| <p>
 | |
|       Because there are many compilers which still use an implementation
 | |
|       that does not have the standard C++-library in namespace
 | |
|       <b>std::</b>, some care is required to support these as
 | |
|       well.
 | |
|     </p>
 | |
| <p>
 | |
|       Namespace back-portability-issues are generally not a problem with
 | |
|       g++, because versions of g++ that do not have libstdc++ in
 | |
|       <b>std::</b> use <b>-fno-honor-std</b>
 | |
|       (ignore <b>std::</b>, <b>:: = std::</b>) by
 | |
|       default. That is, the responsibility for enabling or disabling
 | |
|       <b>std::</b> is on the user; the maintainer does not have
 | |
|       to care about it. This probably applies to some other compilers as
 | |
|       well.
 | |
|     </p>
 | |
| <p>
 | |
|       The following sections list some possible solutions to support compilers
 | |
|       that cannot ignore std::.
 | |
|     </p>
 | |
| <div class="section">
 | |
| <div class="titlepage"><div><h3 class="title">
 | |
| <a name="sec-gtkmm-hack"></a>Using <span class="emphasis"><i>namespace
 | |
| 	  composition</i></span> if the project uses a separate
 | |
| 	namespace</h3></div></div>
 | |
| <p>
 | |
| 	<a href="http://gtkmm.sourceforge.net" target="_top">Gtk--</a> defines
 | |
| 	most of its classes in namespace Gtk::. Thus, it was possible to
 | |
| 	adapt Gtk-- to namespace std:: by using a C++-feature called
 | |
| 	<span class="emphasis"><i>namespace composition</i></span>. This is what happens if
 | |
| 	you put a <span class="emphasis"><i>using</i></span>-declaration into a
 | |
| 	namespace-definition: the imported symbol(s) gets imported into the
 | |
| 	currently active namespace(s). For example:
 | |
| 	<pre class="programlisting">
 | |
| 	  namespace Gtk {
 | |
| 	  using std::string;
 | |
| 	  class Window { ... }
 | |
| 	  }
 | |
| 	</pre>
 | |
| 	In this example, <b>std::string</b> gets imported into
 | |
| 	namespace Gtk::.  The result is that you don't have to use
 | |
| 	<b>std::string</b> in this header, but still
 | |
| 	<b>std::string</b> does not get imported into
 | |
| 	the global namespace (::) unless the user does
 | |
| 	<b>using namespace Gtk;</b> (which is not recommended
 | |
| 	practice for Gtk--, so it is not a problem).  Additionally, the
 | |
| 	<b>using</b>-declarations are wrapped in macros that
 | |
| 	are set based on autoconf-tests to either "" or i.e. <b>using
 | |
| 	  std::string;</b> (depending on whether the system has
 | |
| 	libstdc++ in <b>std::</b> 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>
 | |
| </div>
 | |
| <div class="section">
 | |
| <div class="titlepage"><div><h3 class="title">
 | |
| <a name="sec-emptyns"></a>Defining an empty namespace std</h3></div></div>
 | |
| <p>
 | |
| 	By defining an (empty) namespace <b>std::</b> before
 | |
| 	using it, you avoid getting errors on systems where no part of the
 | |
| 	library is in namespace std:
 | |
| 	<pre class="programlisting">
 | |
| 	  namespace std { }
 | |
| 	  using namespace std;
 | |
| 	</pre>
 | |
|       </p>
 | |
| </div>
 | |
| <div class="section">
 | |
| <div class="titlepage"><div><h3 class="title">
 | |
| <a name="sec-avoidfqn"></a>Avoid to use fully qualified names
 | |
| 	(i.e. std::string)</h3></div></div>
 | |
| <p>
 | |
| 	If some compilers complain about <b>using
 | |
| 	  std::string;</b>, and if the "hack" for gtk-- mentioned above
 | |
| 	does not work, then I see two solutions:
 | |
| 	
 | |
| 	<div class="itemizedlist"><ul type="disc">
 | |
| <li><p>
 | |
| 	      Define <b>std::</b> as a macro if the compiler
 | |
| 	      doesn't know about <b>std::</b>.
 | |
| 	      <pre class="programlisting">
 | |
| 		#ifdef OLD_COMPILER
 | |
| 		#define std
 | |
| 		#endif
 | |
| 	      </pre>
 | |
| 	      (thanks to Juergen Heinzl who posted this solution on
 | |
| 	      gnu.gcc.help)
 | |
| 	    </p></li>
 | |
| <li><p>
 | |
| 	      Define a macro NS_STD, which is defined to
 | |
| 	      either "" or "std"
 | |
| 	      based on an autoconf-test. Then you should be able to use
 | |
| 	      <b>NS_STD::string</b>, which will evaluate to
 | |
| 	      <b>::string</b> ("string in the global namespace") on
 | |
| 	      systems that do not put string in std::.  (This is untested)
 | |
| 	    </p></li>
 | |
| </ul></div>
 | |
| 	  
 | |
|       </p>
 | |
| </div>
 | |
| <div class="section">
 | |
| <div class="titlepage"><div><h3 class="title">
 | |
| <a name="sec-osprojects"></a>How some open-source-projects deal
 | |
| 	with this</h3></div></div>
 | |
| <p>
 | |
| 	This information was gathered around May 2000. It may not be correct
 | |
| 	by the time you read this.
 | |
|       </p>
 | |
| <div class="table">
 | |
| <p><b>Table 1. Namespace std:: in Open-Source programs</b></p>
 | |
| <table summary="Namespace std:: in Open-Source programs" border="1">
 | |
| <colgroup>
 | |
| <col>
 | |
| <col>
 | |
| </colgroup>
 | |
| <tbody>
 | |
| <tr>
 | |
| <td><a href="http://www.clanlib.org" target="_top">clanlib</a></td>
 | |
| <td>usual</td>
 | |
| </tr>
 | |
| <tr>
 | |
| <td><a href="http://pingus.seul.org" target="_top">pingus</a></td>
 | |
| <td>usual</td>
 | |
| </tr>
 | |
| <tr>
 | |
| <td><a href="http://www.mozilla.org" target="_top">mozilla</a></td>
 | |
| <td>usual</td>
 | |
| </tr>
 | |
| <tr>
 | |
| <td><a href="http://libsigc.sourceforge.net" target="_top">
 | |
| 		  libsigc++</a></td>
 | |
| <td>conservative-impl</td>
 | |
| </tr>
 | |
| </tbody>
 | |
| </table>
 | |
| </div>
 | |
| <div class="table">
 | |
| <p><b>Table 2. Notations for categories</b></p>
 | |
| <table summary="Notations for categories" border="1">
 | |
| <colgroup>
 | |
| <col>
 | |
| <col>
 | |
| </colgroup>
 | |
| <tbody>
 | |
| <tr>
 | |
| <td>usual</td>
 | |
| <td>mostly fully qualified names and some
 | |
| 		using-declarations (but not in headers)</td>
 | |
| </tr>
 | |
| <tr>
 | |
| <td>none</td>
 | |
| <td>no namespace std at all</td>
 | |
| </tr>
 | |
| <tr>
 | |
| <td>conservative-impl</td>
 | |
| <td>wrap all
 | |
| 		namespace-handling in macros to support compilers without
 | |
| 		namespace-support (no libstdc++ used in headers)</td>
 | |
| </tr>
 | |
| </tbody>
 | |
| </table>
 | |
| </div>
 | |
| <p>
 | |
| 	As you can see, this currently lacks an example of a project
 | |
| 	which uses libstdc++-symbols in headers in a back-portable way
 | |
| 	(except for Gtk--: see the <a href="#sec-gtkmm-hack" title="Using namespace
 | |
| 	  composition if the project uses a separate
 | |
| 	namespace">section on the gtkmm-hack</a>).
 | |
|       </p>
 | |
| </div>
 | |
| </div>
 | |
| <div class="section">
 | |
| <div class="titlepage"><div><h2 class="title" style="clear: both">
 | |
| <a name="sec-nocreate"></a>there is no ios::nocreate/ios::noreplace
 | |
|       in ISO 14882</h2></div></div>
 | |
| <p>
 | |
|       I have seen <b>ios::nocreate</b> being used for
 | |
|       input-streams, most probably because the author thought it would be
 | |
|       more correct to specify nocreate "explicitly".  So you can simply
 | |
|       leave it out for input-streams.
 | |
|     </p>
 | |
| <p>
 | |
|       For output streams, "nocreate" is probably the default, unless you
 | |
|       specify <b>std::ios::trunc</b> ? To be safe, you can open
 | |
|       the file for reading, check if it has been opened, and then decide
 | |
|       whether you want to create/replace or not. To my knowledge, even
 | |
|       older implementations support <b>app</b>,
 | |
|       <b>ate</b> and <b>trunc</b> (except for
 | |
|       <b>app</b> ?).
 | |
|     </p>
 | |
| </div>
 | |
| <div class="section">
 | |
| <div class="titlepage"><div><h2 class="title" style="clear: both">
 | |
| <a name="sec-stream::attach"></a><b>stream::attach(int
 | |
| 	fd)</b> is not in the standard any more</h2></div></div>
 | |
| <p>
 | |
|       Phil Edwards <tt><<a href="mailto:pedwards@disaster.jaj.com">pedwards@disaster.jaj.com</a>></tt> writes:
 | |
|       It was considered and rejected.  Not all environments use file
 | |
|       descriptors.  Of those that do, not all of them use integers to represent
 | |
|       them.
 | |
|     </p>
 | |
| <p>
 | |
|       When using libstdc++-v3, you can use
 | |
|       <div class="funcsynopsis">
 | |
| <pre class="funcsynopsisinfo">
 | |
| 	  #include <fstream>
 | |
| 	</pre>
 | |
| <p><code><code class="funcdef">
 | |
| 	    <b class="fsfunc">basic_filebuf<...>::basic_filebuf<...>
 | |
| 	    </b>
 | |
| 	  </code>(<var class="pdparam">file</var>, <var class="pdparam">mode</var>, <var class="pdparam">size</var>);<br>__c_file_type* <var class="pdparam">file</var>;<br>ios_base::open_mode <var class="pdparam">mode</var>;<br>int <var class="pdparam">size</var>;</code></p>
 | |
| </div>
 | |
|       but the the signature of this constructor has changed often, and
 | |
|       it might change again. For the current state of this, check
 | |
|       <a href="../ext/howto.html" target="_top">the howto for extensions</a>.
 | |
|     </p>
 | |
| <p>
 | |
|       For a portable solution (among systems which use
 | |
|       filedescriptors), you need to implement a subclass of
 | |
|       <b>std::streambuf</b> (or
 | |
|       <b>std::basic_streambuf<..></b>) which opens a file
 | |
|       given a descriptor, and then pass an instance of this to the
 | |
|       stream-constructor.  For an example of this, refer to
 | |
|       <a href="http://www.josuttis.com/cppcode/fdstream.html" target="_top">fdstream example</a> 
 | |
|       by Nicolai Josuttis.
 | |
|     </p>
 | |
| </div>
 | |
| <div class="section">
 | |
| <div class="titlepage"><div><h2 class="title" style="clear: both">
 | |
| <a name="sec-headers"></a>The new headers</h2></div></div>
 | |
| <p>
 | |
|       All new headers can be seen in this <a href="headers_cc.txt" target="_top">
 | |
| 	source-code</a>.
 | |
|     </p>
 | |
| <p>
 | |
|       The old C++-headers (iostream.h etc.) are available, but gcc generates
 | |
|       a warning that you are using deprecated headers.
 | |
|     </p>
 | |
| <div class="section">
 | |
| <div class="titlepage"><div><h3 class="title">
 | |
| <a name="sec-cheaders"></a>New headers replacing C-headers</h3></div></div>
 | |
| <p>
 | |
| 	You should not use the C-headers (except for system-level
 | |
| 	headers) from C++ programs. Instead, you should use a set of
 | |
| 	headers that are named by prepending 'c' and, as usual,
 | |
| 	omitting the extension (.h). For example, instead of using
 | |
| 	<tt><math.h></tt>, you
 | |
| 	should use <tt><cmath></tt>. In some cases this has
 | |
| 	the advantage that the C++-header is more standardized than
 | |
| 	the C-header (i.e. <tt><ctime></tt> (almost)
 | |
| 	corresponds to either <tt><time.h></tt> or <tt><sys/time.h></tt>).
 | |
| 
 | |
| 	The standard specifies that if you include the C-style header
 | |
| 	(<tt><math.h></tt> in
 | |
| 	this case), the symbols will be available both in the global
 | |
| 	namespace and in namespace <b>std::</b> (but
 | |
| 	libstdc++ does not yet have fully compliant headers) On the
 | |
| 	other hand, if you include only the new header (i.e. <tt><cmath></tt>), the symbols
 | |
| 	will only be defined in namespace <b>std::</b>
 | |
| 	(and macros will be converted to inline-functions).
 | |
|       </p>
 | |
| <p>
 | |
| 	For more information on this, and for information on how the
 | |
| 	GNU C++ implementation might reuse ("shadow") the C
 | |
| 	library-functions, have a look at <a href="http://www.cantrip.org/cheaders.html" target="_top">
 | |
| 	  www.cantrip.org</a>.
 | |
|       </p>
 | |
| </div>
 | |
| <div class="section">
 | |
| <div class="titlepage"><div><h3 class="title">
 | |
| <a name="sec-fstream-header"></a>
 | |
| 	<tt><fstream></tt> does
 | |
| 	not define <b>std::cout</b>,
 | |
| 	<b>std::cin</b> etc.</h3></div></div>
 | |
| <p>
 | |
| 	In earlier versions of the standard,
 | |
| 	<tt><fstream.h></tt>,
 | |
| 	<tt><ostream.h></tt>
 | |
| 	and <tt><istream.h></tt>
 | |
| 	used to define
 | |
| 	<b>cout</b>, <b>cin</b> and so on. Because
 | |
| 	of the templatized iostreams in libstdc++-v3, you need to include
 | |
| 	<tt><iostream></tt>
 | |
| 	explicitly to define these.
 | |
|       </p>
 | |
| </div>
 | |
| </div>
 | |
| <div class="section">
 | |
| <div class="titlepage"><div><h2 class="title" style="clear: both">
 | |
| <a name="sec-iterators"></a>Iterators</h2></div></div>
 | |
| <p>
 | |
|       The following are not proper uses of iterators, but may be working
 | |
|       fixes for existing uses of iterators.
 | |
|       <div class="itemizedlist"><ul type="disc">
 | |
| <li><p>you cannot do
 | |
| 	    <b>ostream::operator<<(iterator)</b> to
 | |
| 	    print the address of the iterator => use
 | |
| 	    <b>operator<< &*iterator</b> instead ?
 | |
| 	  </p></li>
 | |
| <li><p>you cannot clear an iterator's reference
 | |
| 	    (<b>iterator = 0</b>) => use
 | |
| 	    <b>iterator = iterator_type();</b> ?
 | |
| 	  </p></li>
 | |
| <li><p>
 | |
| <b>if (iterator)</b> won't work any
 | |
| 	    more => use <b>if (iterator != iterator_type())</b>
 | |
| 	    ?</p></li>
 | |
| </ul></div>
 | |
|     </p>
 | |
| </div>
 | |
| <div class="section">
 | |
| <div class="titlepage"><div><h2 class="title" style="clear: both">
 | |
| <a name="sec-macros"></a>
 | |
|       Libc-macros (i.e. <b>isspace</b> from
 | |
|       <tt><cctype></tt>)</h2></div></div>
 | |
| <p>
 | |
|       Glibc 2.0.x and 2.1.x define the
 | |
|       <tt><ctype.h></tt>
 | |
|       -functionality as macros (isspace, isalpha etc.). Libstdc++-v3
 | |
|       "shadows" these macros as described in the <a href="#sec-cheaders" title="New headers replacing C-headers">section about
 | |
| 	c-headers</a>.
 | |
|     </p>
 | |
| <p>
 | |
|       Older implementations of libstdc++ (g++-2 for egcs 1.x and g++-3
 | |
|       for gcc 2.95.x), however, keep these functions as macros, and so it
 | |
|       is not back-portable to use fully qualified names. For example:
 | |
|       <pre class="programlisting">
 | |
| 	#include <cctype>
 | |
| 	int main() { std::isspace('X'); }
 | |
|       </pre>
 | |
|       will result in something like this (unless using g++-v3):
 | |
|       <pre class="programlisting">
 | |
| 	std:: (__ctype_b[(int) ( ( 'X' ) )] & (unsigned short int)
 | |
| 	_ISspace )  ;
 | |
|       </pre>
 | |
|     </p>
 | |
| <p>
 | |
|       One solution I can think of is to test for -v3 using
 | |
|       autoconf-macros, and define macros for each of the C-functions
 | |
|       (maybe that is possible with one "wrapper" macro as well ?).
 | |
|     </p>
 | |
| <p>
 | |
|       Another solution which would fix g++ is to tell the user to modify a
 | |
|       header-file so that g++-2 (egcs 1.x) and g++-3 (gcc 2.95.x) define a
 | |
|       macro which tells <tt><ctype.h></tt> to define functions
 | |
|       instead of macros:
 | |
|       <pre class="programlisting">
 | |
| 	// This keeps isalnum, et al from being propagated as macros.
 | |
| 	#if __linux__
 | |
| 	#define __NO_CTYPE 1
 | |
| 	#endif
 | |
| 
 | |
| 	[ now include <ctype.h> ]
 | |
|       </pre>
 | |
|     </p>
 | |
| <p>
 | |
|       Another problem arises if you put a <b>using namespace
 | |
| 	std;</b> declaration at the top, and include <tt><ctype.h></tt>. This will result in
 | |
|       ambiguities between the definitions in the global namespace
 | |
|       (<tt><ctype.h></tt>) and the
 | |
|       definitions in namespace <b>std::</b>
 | |
|       (<b><cctype></b>).
 | |
|     </p>
 | |
| <p>
 | |
|       The solution to this problem was posted to the libstdc++-v3
 | |
|       mailing-list:
 | |
|       Benjamin Kosnik <tt><<a href="mailto:bkoz@redhat.com">bkoz@redhat.com</a>></tt> writes:
 | |
|       ‘
 | |
| 	--enable-cshadow-headers is currently broken. As a result, shadow
 | |
| 	headers are not being searched....
 | |
|       ’
 | |
|       This is now outdated, but gcc 3.0 still does not have fully
 | |
|       compliant "shadow headers".
 | |
|     </p>
 | |
| </div>
 | |
| <div class="section">
 | |
| <div class="titlepage"><div><h2 class="title" style="clear: both">
 | |
| <a name="sec-stream-state"></a>State of streams</h2></div></div>
 | |
| <p>
 | |
|       At least some older implementations don't have
 | |
|       <b>std::ios_base</b>, so you should use
 | |
|       <b>std::ios::badbit</b>, <b>std::ios::failbit</b>
 | |
|       and <b>std::ios::eofbit</b> and
 | |
|       <b>std::ios::goodbit</b>.
 | |
|     </p>
 | |
| </div>
 | |
| <div class="section">
 | |
| <div class="titlepage"><div><h2 class="title" style="clear: both">
 | |
| <a name="sec-vector-at"></a>vector::at is missing (i.e. gcc 2.95.x)</h2></div></div>
 | |
| <p>
 | |
|       One solution is to add an autoconf-test for this:
 | |
|       <pre class="programlisting">
 | |
| 	AC_MSG_CHECKING(for container::at)
 | |
| 	AC_TRY_COMPILE(
 | |
| 	[
 | |
| 	#include <vector>
 | |
| 	#include <deque>
 | |
| 	#include <string>
 | |
| 	
 | |
| 	using namespace std;
 | |
| 	],
 | |
| 	[
 | |
| 	deque<int> test_deque(3);
 | |
| 	test_deque.at(2);
 | |
| 	vector<int> test_vector(2);
 | |
| 	test_vector.at(1);
 | |
| 	string test_string("test_string");
 | |
| 	test_string.at(3);
 | |
| 	],
 | |
| 	[AC_MSG_RESULT(yes)
 | |
| 	AC_DEFINE(HAVE_CONTAINER_AT)],
 | |
| 	[AC_MSG_RESULT(no)])
 | |
|       </pre>
 | |
|       If you are using other (non-GNU) compilers it might be a good idea
 | |
|       to check for <b>string::at</b> separately.
 | |
|     </p>
 | |
| </div>
 | |
| <div class="section">
 | |
| <div class="titlepage"><div><h2 class="title" style="clear: both">
 | |
| <a name="sec-eof"></a>Using std::char_traits<char>::eof()</h2></div></div>
 | |
| <p>
 | |
|       <pre class="programlisting">
 | |
| 	#ifdef HAVE_CHAR_TRAITS
 | |
| 	#define CPP_EOF std::char_traits<char>::eof()
 | |
| 	#else
 | |
| 	#define CPP_EOF EOF
 | |
| 	#endif
 | |
|       </pre>
 | |
|     </p>
 | |
| </div>
 | |
| <div class="section">
 | |
| <div class="titlepage"><div><h2 class="title" style="clear: both">
 | |
| <a name="sec-string-clear"></a>Using string::clear()/string::erase()</h2></div></div>
 | |
| <p>
 | |
|       There are two functions for deleting the contents of a string:
 | |
|       <b>clear</b> and <b>erase</b> (the latter
 | |
|       returns the string).
 | |
|       <pre class="programlisting">
 | |
| 	void 
 | |
| 	clear() { _M_mutate(0, this->size(), 0); }
 | |
|       </pre>
 | |
|       <pre class="programlisting">
 | |
| 	basic_string& 
 | |
| 	erase(size_type __pos = 0, size_type __n = npos)
 | |
| 	{ 
 | |
| 	return this->replace(_M_check(__pos), _M_fold(__pos, __n),
 | |
| 	_M_data(), _M_data()); 
 | |
| 	}
 | |
|       </pre>
 | |
|       The implementation of <b>erase</b> seems to be more
 | |
|       complicated (from libstdc++-v3), but <b>clear</b> is not
 | |
|       implemented in gcc 2.95.x's libstdc++, so you should use
 | |
|       <b>erase</b> (which is probably faster than
 | |
|       <b>operator=(charT*)</b>).
 | |
|     </p>
 | |
| </div>
 | |
| <div class="section">
 | |
| <div class="titlepage"><div><h2 class="title" style="clear: both">
 | |
| <a name="sec-scan-form"></a>GNU Extensions ostream::form and istream::scan</h2></div></div>
 | |
| <p>
 | |
|       These	are not supported any more - use
 | |
|       <a href="#sec-stringstream" title="Using stringstreams">
 | |
| 	stringstreams</a> instead.	
 | |
|     </p>
 | |
| </div>
 | |
| <div class="section">
 | |
| <div class="titlepage"><div><h2 class="title" style="clear: both">
 | |
| <a name="sec-stringstream"></a>Using stringstreams</h2></div></div>
 | |
| <p>
 | |
|       Libstdc++-v3 provides the new
 | |
|       <b>i/ostringstream</b>-classes, (<tt><sstream></tt>), but for compatibility
 | |
|       with older implementations you still have to use
 | |
|       <b>i/ostrstream</b> (<tt><strstream></tt>):
 | |
|       <pre class="programlisting">
 | |
| 	#ifdef HAVE_SSTREAM
 | |
| 	#include <sstream>
 | |
| 	#else
 | |
| 	#include <strstream>
 | |
| 	#endif
 | |
|       </pre>
 | |
|       <div class="itemizedlist"><ul type="disc">
 | |
| <li><p> <b>strstream</b> is considered to be
 | |
| 	    deprecated
 | |
| 	  </p></li>
 | |
| <li><p> <b>strstream</b> is limited to
 | |
| 	    <b>char</b>
 | |
| 	  </p></li>
 | |
| <li><p> with <b>ostringstream</b> you don't
 | |
| 	    have to take care of terminating the string or freeing its
 | |
| 	    memory
 | |
| 	  </p></li>
 | |
| <li><p> <b>istringstream</b> can be re-filled
 | |
| 	    (clear(); str(input);)
 | |
| 	  </p></li>
 | |
| </ul></div>
 | |
|     </p>
 | |
| <p>
 | |
|       You can then use output-stringstreams like this:
 | |
|       <pre class="programlisting">
 | |
| 	#ifdef HAVE_SSTREAM
 | |
| 	std::ostringstream oss;
 | |
| 	#else
 | |
| 	std::ostrstream oss;
 | |
| 	#endif
 | |
| 	oss << "Name=" << m_name << ", number=" << m_number << std::endl;
 | |
| 	...
 | |
| 	#ifndef HAVE_SSTREAM
 | |
| 	oss << std::ends; // terminate the char*-string
 | |
| 	#endif
 | |
| 	// str() returns char* for ostrstream and a string for ostringstream
 | |
| 	// this also causes ostrstream to think that the buffer's memory
 | |
| 	// is yours
 | |
| 	m_label.set_text(oss.str());
 | |
| 	#ifndef HAVE_SSTREAM
 | |
| 	// let the ostrstream take care of freeing the memory
 | |
| 	oss.freeze(false);
 | |
| 	#endif
 | |
|       </pre>
 | |
|     </p>
 | |
| <p>
 | |
|       Input-stringstreams can be used similarly:
 | |
|       <pre class="programlisting">
 | |
| 	std::string input;
 | |
| 	...
 | |
| 	#ifdef HAVE_SSTREAM
 | |
| 	std::istringstream iss(input);
 | |
| 	#else
 | |
| 	std::istrstream iss(input.c_str());
 | |
| 	#endif
 | |
| 	int i;
 | |
| 	iss >> i; 
 | |
|       </pre>
 | |
|       One (the only?) restriction is that an istrstream cannot be re-filled:
 | |
|       <pre class="programlisting">
 | |
| 	std::istringstream iss(numerator);
 | |
| 	iss >> m_num;
 | |
| 	// this is not possible with istrstream
 | |
| 	iss.clear();
 | |
| 	iss.str(denominator);
 | |
| 	iss >> m_den;
 | |
|       </pre>
 | |
|       If you don't care about speed, you can put these conversions in
 | |
|       a template-function:
 | |
|       <pre class="programlisting">
 | |
| 	template <class X>
 | |
| 	void fromString(const string& input, X& any)
 | |
| 	{
 | |
| 	#ifdef HAVE_SSTREAM
 | |
| 	std::istringstream iss(input);
 | |
| 	#else
 | |
| 	std::istrstream iss(input.c_str());
 | |
| 	#endif
 | |
| 	X temp;
 | |
| 	iss >> temp;
 | |
| 	if (iss.fail())
 | |
| 	throw runtime_error(..)
 | |
| 	any = temp;
 | |
| 	}
 | |
|       </pre>
 | |
|       Another example of using stringstreams is in <a href="../21_strings/howto.html" target="_top">this howto</a>.
 | |
|     </p>
 | |
| <p>
 | |
|       I have read the Josuttis book on Standard C++, so some information
 | |
|       comes from there. Additionally, there is information in
 | |
|       "info iostream", which covers the old implementation that gcc 2.95.x
 | |
|       uses.
 | |
|     </p>
 | |
| </div>
 | |
| <div class="section">
 | |
| <div class="titlepage"><div><h2 class="title" style="clear: both">
 | |
| <a name="sec-about"></a>About...</h2></div></div>
 | |
| <p>
 | |
|       Please send any experience, additions, corrections or questions to
 | |
|       <a href="mailto:fnatter@gmx.net" target="_top">fnatter@gmx.net</a> or for
 | |
|       discussion to the libstdc++-v3-mailing-list.
 | |
|     </p>
 | |
| </div>
 | |
| </div></body>
 | |
| </html>
 |