mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-02-07 02:19:31 +08:00
re PR libstdc++/14991 (stream::attach(int fd) porting entry out-of-date)
2007-01-13 Paolo Carlini <pcarlini@suse.de> PR libstdc++/14991 * docs/html/17_intro/porting-howto.html ([3]): Mention stdio_filebuf. * docs/html/17_intro/porting-howto.xml: Remove. * docs/html/17_intro/porting-howto.html: Remove spurious end tags pointed out by validator.w3.org. From-SVN: r120749
This commit is contained in:
parent
8bcd6380d1
commit
d8867564fe
@ -1,3 +1,12 @@
|
||||
2007-01-13 Paolo Carlini <pcarlini@suse.de>
|
||||
|
||||
PR libstdc++/14991
|
||||
* docs/html/17_intro/porting-howto.html ([3]): Mention stdio_filebuf.
|
||||
* docs/html/17_intro/porting-howto.xml: Remove.
|
||||
|
||||
* docs/html/17_intro/porting-howto.html: Remove spurious end tags
|
||||
pointed out by validator.w3.org.
|
||||
|
||||
2007-01-12 Paolo Carlini <pcarlini@suse.de>
|
||||
|
||||
PR libstdc++/30416 (continued)
|
||||
|
@ -113,7 +113,7 @@
|
||||
with this</a>
|
||||
</dt>
|
||||
</dl></dd>
|
||||
<dt>2. <a href="#sec-nocreate">there is no ios::nocreate/ios::noreplace
|
||||
<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
|
||||
@ -182,7 +182,6 @@
|
||||
<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
|
||||
@ -235,7 +234,6 @@
|
||||
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">
|
||||
@ -248,7 +246,6 @@
|
||||
namespace std { }
|
||||
using namespace std;
|
||||
</pre>
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><h3 class="title">
|
||||
@ -270,7 +267,7 @@
|
||||
</pre>
|
||||
(thanks to Juergen Heinzl who posted this solution on
|
||||
gnu.gcc.help)
|
||||
</p></li>
|
||||
</li>
|
||||
<li><p>
|
||||
Define a macro NS_STD, which is defined to
|
||||
either "" or "std"
|
||||
@ -280,8 +277,6 @@
|
||||
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">
|
||||
@ -356,7 +351,7 @@
|
||||
</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
|
||||
<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
|
||||
@ -383,22 +378,8 @@
|
||||
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>
|
||||
|
||||
<p>
|
||||
For a portable solution (among systems which use
|
||||
filedescriptors), you need to implement a subclass of
|
||||
@ -409,6 +390,14 @@
|
||||
<a href="http://www.josuttis.com/cppcode/fdstream.html" target="_top">fdstream example</a>
|
||||
by Nicolai Josuttis.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
An extension is also available:
|
||||
<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.
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><h2 class="title" style="clear: both">
|
||||
@ -491,7 +480,6 @@
|
||||
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">
|
||||
@ -518,7 +506,6 @@
|
||||
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
|
||||
@ -537,7 +524,6 @@
|
||||
|
||||
[ 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
|
||||
@ -598,7 +584,6 @@
|
||||
</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">
|
||||
@ -611,7 +596,6 @@
|
||||
#define CPP_EOF EOF
|
||||
#endif
|
||||
</pre>
|
||||
</p>
|
||||
</div>
|
||||
<div class="section">
|
||||
<div class="titlepage"><div><h2 class="title" style="clear: both">
|
||||
@ -637,7 +621,6 @@
|
||||
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">
|
||||
@ -678,7 +661,6 @@
|
||||
(clear(); str(input);)
|
||||
</p></li>
|
||||
</ul></div>
|
||||
</p>
|
||||
<p>
|
||||
You can then use output-stringstreams like this:
|
||||
<pre class="programlisting">
|
||||
@ -701,7 +683,6 @@
|
||||
oss.freeze(false);
|
||||
#endif
|
||||
</pre>
|
||||
</p>
|
||||
<p>
|
||||
Input-stringstreams can be used similarly:
|
||||
<pre class="programlisting">
|
||||
@ -743,7 +724,6 @@
|
||||
}
|
||||
</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
|
||||
|
@ -1,785 +0,0 @@
|
||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
|
||||
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.1//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.0/docbookx.dtd">
|
||||
|
||||
<?xml-stylesheet type="text/xsl" href="docbook-xslt/docbook/html/docbook.xsl"?>
|
||||
|
||||
<!--
|
||||
This is written using docbook 4.1 xml. HTML is generated using
|
||||
the xslt-stylesheets from http://www.nwalsh.com.
|
||||
|
||||
xsltproc is an xslt-processor included in libxslt:
|
||||
(http://xmlsoft.org/XSLT/ or here:
|
||||
ftp://ftp.gnome.org/pub/GNOME/unstable/sources/libxslt/)
|
||||
(it requires libxml2: http://xmlsoft.org
|
||||
or here: ftp://ftp.gnome.org/pub/GNOME/stable/sources/libxml/)
|
||||
|
||||
You can find the latest version of this document here:
|
||||
http://gcc.gnu.org/onlinedocs/libstdc++/17_intro/porting-howto(.html|.xml)
|
||||
-->
|
||||
|
||||
<!-- TODO:
|
||||
o remove //@label: use automatic numbering
|
||||
o make this work: <link linkend="sec-gtkmm-hack" endterm="sec-gtkmm-hack.title"/>.
|
||||
o clean up the section-numbering
|
||||
-->
|
||||
|
||||
<article class = "whitepaper" id = "libstdc++-porting-howto" lang = "en">
|
||||
<articleinfo>
|
||||
<title>Libstdc++-porting-howto</title>
|
||||
<author>
|
||||
<firstname>Felix</firstname>
|
||||
<surname>Natter</surname>
|
||||
</author>
|
||||
<address>
|
||||
<email>fnatter@gmx.net</email>
|
||||
</address>
|
||||
<revhistory>
|
||||
<revision>
|
||||
<revnumber>0.5</revnumber>
|
||||
<date>Thu Jun 1 13:06:50 2000</date>
|
||||
<authorinitials>fnatter</authorinitials>
|
||||
<revremark>First docbook-version.</revremark>
|
||||
</revision>
|
||||
<revision>
|
||||
<revnumber>0.8</revnumber>
|
||||
<date>Sun Jul 30 20:28:40 2000</date>
|
||||
<authorinitials>fnatter</authorinitials>
|
||||
<revremark>First released version using docbook-xml
|
||||
+ second upload to libstdc++-page.
|
||||
</revremark>
|
||||
</revision>
|
||||
<revision>
|
||||
<revnumber>0.9</revnumber>
|
||||
<date>Wed Sep 6 02:59:32 2000</date>
|
||||
<authorinitials>fnatter</authorinitials>
|
||||
<revremark>5 new sections.</revremark>
|
||||
</revision>
|
||||
<revision>
|
||||
<revnumber>0.9.1</revnumber>
|
||||
<date>Sat Sep 23 14:20:15 2000</date>
|
||||
<authorinitials>fnatter</authorinitials>
|
||||
<revremark>added information about why file-descriptors are not in the
|
||||
standard</revremark>
|
||||
</revision>
|
||||
<revision>
|
||||
<revnumber>0.9.2</revnumber>
|
||||
<date>Tue Jun 5 20:07:49 2001</date>
|
||||
<authorinitials>fnatter</authorinitials>
|
||||
<revremark>
|
||||
a fix, added hint on increased portability of C-shadow-headers,
|
||||
added autoconf-test HAVE_CONTAINER_AT
|
||||
</revremark>
|
||||
</revision>
|
||||
<revision>
|
||||
<revnumber>0.9.3</revnumber>
|
||||
<date>Fri Jun 29 16:15:56 2001</date>
|
||||
<authorinitials>fnatter</authorinitials>
|
||||
<revremark>
|
||||
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
|
||||
</revremark>
|
||||
</revision>
|
||||
<revision>
|
||||
<revnumber>0.9.4</revnumber>
|
||||
<date>Mon Nov 5 17:01:04 2001</date>
|
||||
<authorinitials>fnatter</authorinitials>
|
||||
<revremark>
|
||||
rewrite section 1.1.3 because of gnu.gcc.help-post by
|
||||
Juergen Heinzl
|
||||
</revremark>
|
||||
</revision>
|
||||
</revhistory>
|
||||
<legalnotice><title>Legal Notice</title>
|
||||
<para>
|
||||
This document can be distributed under the FDL
|
||||
(<ulink url = "http://www.gnu.org">www.gnu.org</ulink>)
|
||||
</para>
|
||||
</legalnotice>
|
||||
|
||||
<pubdate>Tue Jun 5 20:07:49 2001</pubdate>
|
||||
<abstract>
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
</abstract>
|
||||
</articleinfo>
|
||||
|
||||
<para>
|
||||
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".
|
||||
</para>
|
||||
|
||||
<section id="sec-nsstd" label="1"><title>Namespace std::</title>
|
||||
<para>
|
||||
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:
|
||||
<itemizedlist>
|
||||
|
||||
<listitem><para>wrap your code in <command>namespace std {
|
||||
... }</command> => This is not an option because only symbols
|
||||
from the standard c++-library are defined in namespace std::.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>put a kind of
|
||||
<emphasis>using-declaration</emphasis> in your source (either
|
||||
<command>using namespace std;</command> or i.e. <command>using
|
||||
std::string;</command>) => works well for source-files, but
|
||||
cannot be used in header-files.
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>use a <emphasis>fully qualified name</emphasis> for
|
||||
each libstdc++-symbol (i.e. <command>std::string</command>,
|
||||
<command>std::cout</command>) => can always be used
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Because there are many compilers which still use an implementation
|
||||
that does not have the standard C++-library in namespace
|
||||
<command>std::</command>, some care is required to support these as
|
||||
well.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
Namespace back-portability-issues are generally not a problem with
|
||||
g++, because versions of g++ that do not have libstdc++ in
|
||||
<command>std::</command> use <command>-fno-honor-std</command>
|
||||
(ignore <command>std::</command>, <command>:: = std::</command>) by
|
||||
default. That is, the responsibility for enabling or disabling
|
||||
<command>std::</command> is on the user; the maintainer does not have
|
||||
to care about it. This probably applies to some other compilers as
|
||||
well.
|
||||
</para>
|
||||
<para>
|
||||
The following sections list some possible solutions to support compilers
|
||||
that cannot ignore std::.
|
||||
</para>
|
||||
|
||||
<section id = "sec-gtkmm-hack" label = "1.1">
|
||||
<title id="sec-gtkmm-hack.title">Using <emphasis>namespace
|
||||
composition</emphasis> if the project uses a separate
|
||||
namespace</title>
|
||||
<para>
|
||||
<ulink url = "http://gtkmm.sourceforge.net">Gtk--</ulink> defines
|
||||
most of its classes in namespace Gtk::. Thus, it was possible to
|
||||
adapt Gtk-- to namespace std:: by using a C++-feature called
|
||||
<emphasis>namespace composition</emphasis>. This is what happens if
|
||||
you put a <emphasis>using</emphasis>-declaration into a
|
||||
namespace-definition: the imported symbol(s) gets imported into the
|
||||
currently active namespace(s). For example:
|
||||
<programlisting>
|
||||
namespace Gtk {
|
||||
using std::string;
|
||||
class Window { ... }
|
||||
}
|
||||
</programlisting>
|
||||
In this example, <command>std::string</command> gets imported into
|
||||
namespace Gtk::. The result is that you don't have to use
|
||||
<command>std::string</command> in this header, but still
|
||||
<command>std::string</command> does not get imported into
|
||||
the global namespace (::) unless the user does
|
||||
<command>using namespace Gtk;</command> (which is not recommended
|
||||
practice for Gtk--, so it is not a problem). Additionally, the
|
||||
<command>using</command>-declarations are wrapped in macros that
|
||||
are set based on autoconf-tests to either "" or i.e. <command>using
|
||||
std::string;</command> (depending on whether the system has
|
||||
libstdc++ in <command>std::</command> or not). (ideas from
|
||||
<email>llewelly@dbritsch.dsl.xmission.com</email>, Karl Nelson
|
||||
<email>kenelson@ece.ucdavis.edu</email>)
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id = "sec-emptyns" label = "1.2">
|
||||
<title id="sec-emptyns.title">Defining an empty namespace std</title>
|
||||
<para>
|
||||
By defining an (empty) namespace <command>std::</command> before
|
||||
using it, you avoid getting errors on systems where no part of the
|
||||
library is in namespace std:
|
||||
<programlisting>
|
||||
namespace std { }
|
||||
using namespace std;
|
||||
</programlisting>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id = "sec-avoidfqn" label = "1.3">
|
||||
<title id="sec-avoidfqn.title">Avoid to use fully qualified names
|
||||
(i.e. std::string)</title>
|
||||
<para>
|
||||
If some compilers complain about <command>using
|
||||
std::string;</command>, and if the "hack" for gtk-- mentioned above
|
||||
does not work, then I see two solutions:
|
||||
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
Define <command>std::</command> as a macro if the compiler
|
||||
doesn't know about <command>std::</command>.
|
||||
<programlisting>
|
||||
#ifdef OLD_COMPILER
|
||||
#define std
|
||||
#endif
|
||||
</programlisting>
|
||||
(thanks to Juergen Heinzl who posted this solution on
|
||||
gnu.gcc.help)
|
||||
</para></listitem>
|
||||
|
||||
<listitem><para>
|
||||
Define a macro <symbol>NS_STD</symbol>, which is defined to
|
||||
either "" or "std"
|
||||
based on an autoconf-test. Then you should be able to use
|
||||
<command>NS_STD::string</command>, which will evaluate to
|
||||
<command>::string</command> ("string in the global namespace") on
|
||||
systems that do not put string in std::. (This is untested)
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id = "sec-osprojects" label = "1.4">
|
||||
<title id="sec-osprojects.title">How some open-source-projects deal
|
||||
with this</title>
|
||||
<para>
|
||||
This information was gathered around May 2000. It may not be correct
|
||||
by the time you read this.
|
||||
</para>
|
||||
<table><title>Namespace std:: in Open-Source programs</title>
|
||||
<tgroup cols = "2">
|
||||
<tbody>
|
||||
<row>
|
||||
<entry><ulink url = "http://www.clanlib.org">clanlib</ulink>
|
||||
</entry>
|
||||
<entry>usual</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><ulink url = "http://pingus.seul.org">pingus</ulink>
|
||||
</entry>
|
||||
<entry>usual</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><ulink url = "http://www.mozilla.org">mozilla</ulink>
|
||||
</entry>
|
||||
<entry>usual</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><ulink url = "http://libsigc.sourceforge.net">
|
||||
libsigc++</ulink></entry>
|
||||
<entry>conservative-impl</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<table><title>Notations for categories</title>
|
||||
<tgroup cols = "2">
|
||||
<tbody>
|
||||
<row>
|
||||
<entry>usual</entry>
|
||||
<entry>mostly fully qualified names and some
|
||||
using-declarations (but not in headers)</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>none</entry> <entry>no namespace std at all</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry>conservative-impl</entry>
|
||||
<entry>wrap all
|
||||
namespace-handling in macros to support compilers without
|
||||
namespace-support (no libstdc++ used in headers)</entry>
|
||||
</row>
|
||||
</tbody>
|
||||
</tgroup>
|
||||
</table>
|
||||
|
||||
<para>
|
||||
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 <link linkend="sec-gtkmm-hack"
|
||||
endterm="sec-gtkmm-hack.title">section on the gtkmm-hack</link>).
|
||||
</para>
|
||||
</section>
|
||||
</section> <!-- end of namespace-section -->
|
||||
|
||||
<section id = "sec-nocreate" label = "2">
|
||||
<title id="sec-nocreate.title">there is no ios::nocreate/ios::noreplace
|
||||
in ISO 14882</title>
|
||||
<para>
|
||||
I have seen <command>ios::nocreate</command> 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.
|
||||
</para>
|
||||
<para>
|
||||
For output streams, "nocreate" is probably the default, unless you
|
||||
specify <command>std::ios::trunc</command> ? 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 <command>app</command>,
|
||||
<command>ate</command> and <command>trunc</command> (except for
|
||||
<command>app</command> ?).
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id = "sec-stream::attach" label = "3">
|
||||
<title id="sec-stream::attach.title"><command>stream::attach(int
|
||||
fd)</command> is not in the standard any more</title>
|
||||
<para>
|
||||
Phil Edwards <email>pedwards@disaster.jaj.com</email> 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.
|
||||
</para>
|
||||
<para>
|
||||
When using libstdc++-v3, you can use
|
||||
<funcsynopsis>
|
||||
<funcsynopsisinfo format="linespecific">
|
||||
#include <fstream>
|
||||
</funcsynopsisinfo>
|
||||
<funcprototype>
|
||||
<funcdef>
|
||||
<function>basic_filebuf<...>::basic_filebuf<...>
|
||||
</function>
|
||||
</funcdef>
|
||||
<paramdef>__c_file_type* <parameter>file</parameter></paramdef>
|
||||
<paramdef>ios_base::open_mode <parameter>mode</parameter></paramdef>
|
||||
<paramdef>int <parameter>size</parameter></paramdef>
|
||||
</funcprototype>
|
||||
</funcsynopsis>
|
||||
but the signature of this constructor has changed often, and
|
||||
it might change again. For the current state of this, check
|
||||
<ulink url="../ext/howto.html">the howto for extensions</ulink>.
|
||||
</para>
|
||||
<para>
|
||||
For a portable solution (among systems which use
|
||||
filedescriptors), you need to implement a subclass of
|
||||
<command>std::streambuf</command> (or
|
||||
<command>std::basic_streambuf<..></command>) 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
|
||||
<ulink url="http://www.josuttis.com/cppcode/fdstream.html">fdstream example</ulink>
|
||||
by Nicolai Josuttis.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id = "sec-headers" label = "4">
|
||||
<title id="sec-headers.title">The new headers</title>
|
||||
<para>
|
||||
All new headers can be seen in this <ulink url="headers_cc.txt">
|
||||
source-code</ulink>.
|
||||
</para>
|
||||
<para>
|
||||
The old C++-headers (iostream.h etc.) are available, but gcc generates
|
||||
a warning that you are using deprecated headers.
|
||||
</para>
|
||||
|
||||
<section id = "sec-cheaders" label = "4.1">
|
||||
<title id="sec-cheaders.title">New headers replacing C-headers</title>
|
||||
<para>
|
||||
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
|
||||
<filename class="headerfile"><math.h></filename>, you
|
||||
should use <filename class =
|
||||
"headerfile"><cmath></filename>. In some cases this has
|
||||
the advantage that the C++-header is more standardized than
|
||||
the C-header (i.e. <filename
|
||||
class="headerfile"><ctime></filename> (almost)
|
||||
corresponds to either <filename class =
|
||||
"headerfile"><time.h></filename> or <filename class =
|
||||
"headerfile"><sys/time.h></filename>).
|
||||
|
||||
The standard specifies that if you include the C-style header
|
||||
(<filename class = "headerfile"><math.h></filename> in
|
||||
this case), the symbols will be available both in the global
|
||||
namespace and in namespace <command>std::</command> (but
|
||||
libstdc++ does not yet have fully compliant headers) On the
|
||||
other hand, if you include only the new header (i.e. <filename
|
||||
class = "headerfile"><cmath></filename>), the symbols
|
||||
will only be defined in namespace <command>std::</command>
|
||||
(and macros will be converted to inline-functions).
|
||||
</para>
|
||||
<para>
|
||||
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 <ulink
|
||||
url="http://www.cantrip.org/cheaders.html">
|
||||
www.cantrip.org</ulink>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id = "sec-fstream-header" label = "4.2">
|
||||
<title id="sec-fstream-header.title">
|
||||
<filename class="headerfile"><fstream></filename> does
|
||||
not define <command>std::cout</command>,
|
||||
<command>std::cin</command> etc.</title>
|
||||
<para>
|
||||
In earlier versions of the standard,
|
||||
<filename class="headerfile"><fstream.h></filename>,
|
||||
<filename class="headerfile"><ostream.h></filename>
|
||||
and <filename class="headerfile"><istream.h></filename>
|
||||
used to define
|
||||
<command>cout</command>, <command>cin</command> and so on. Because
|
||||
of the templatized iostreams in libstdc++-v3, you need to include
|
||||
<filename class = "headerfile"><iostream></filename>
|
||||
explicitly to define these.
|
||||
</para>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id = "sec-iterators" label = "5">
|
||||
<title id="sec-iterators.title">Iterators</title>
|
||||
<para>
|
||||
The following are not proper uses of iterators, but may be working
|
||||
fixes for existing uses of iterators.
|
||||
<itemizedlist>
|
||||
<listitem><para>you cannot do
|
||||
<command>ostream::operator<<(iterator)</command> to
|
||||
print the address of the iterator => use
|
||||
<command>operator<< &*iterator</command> instead ?
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem><para>you cannot clear an iterator's reference
|
||||
(<command>iterator = 0</command>) => use
|
||||
<command>iterator = iterator_type();</command> ?
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem><para><command>if (iterator)</command> won't work any
|
||||
more => use <command>if (iterator != iterator_type())</command>
|
||||
?</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id = "sec-macros" label = "6">
|
||||
<title id="sec-macros.title">
|
||||
Libc-macros (i.e. <command>isspace</command> from
|
||||
<filename class = "headerfile"><cctype></filename>)</title>
|
||||
<para>
|
||||
Glibc 2.0.x and 2.1.x define the
|
||||
<filename class="headerfile"><ctype.h></filename>
|
||||
-functionality as macros (isspace, isalpha etc.). Libstdc++-v3
|
||||
"shadows" these macros as described in the <link
|
||||
linkend="sec-cheaders" endterm="sec-cheaders.title">section about
|
||||
c-headers</link>.
|
||||
</para>
|
||||
<para>
|
||||
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:
|
||||
<programlisting>
|
||||
#include <cctype>
|
||||
int main() { std::isspace('X'); }
|
||||
</programlisting>
|
||||
will result in something like this (unless using g++-v3):
|
||||
<programlisting>
|
||||
std:: (__ctype_b[(int) ( ( 'X' ) )] & (unsigned short int)
|
||||
_ISspace ) ;
|
||||
</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
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 ?).
|
||||
</para>
|
||||
<para>
|
||||
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 <filename
|
||||
class="headerfile"><ctype.h></filename> to define functions
|
||||
instead of macros:
|
||||
<programlisting>
|
||||
// This keeps isalnum, et al from being propagated as macros.
|
||||
#if __linux__
|
||||
#define __NO_CTYPE 1
|
||||
#endif
|
||||
|
||||
[ now include <ctype.h> ]
|
||||
</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Another problem arises if you put a <command>using namespace
|
||||
std;</command> declaration at the top, and include <filename class
|
||||
= "headerfile"><ctype.h></filename>. This will result in
|
||||
ambiguities between the definitions in the global namespace
|
||||
(<filename class = "headerfile"><ctype.h></filename>) and the
|
||||
definitions in namespace <command>std::</command>
|
||||
(<command><cctype></command>).
|
||||
</para>
|
||||
<para>
|
||||
The solution to this problem was posted to the libstdc++-v3
|
||||
mailing-list:
|
||||
Benjamin Kosnik <email>bkoz@redhat.com</email> writes:
|
||||
<quote>
|
||||
--enable-cshadow-headers is currently broken. As a result, shadow
|
||||
headers are not being searched....
|
||||
</quote>
|
||||
This is now outdated, but gcc 3.0 still does not have fully
|
||||
compliant "shadow headers".
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="sec-stream-state" label="7">
|
||||
<title id="sec-stream-state.title">State of streams</title>
|
||||
<para>
|
||||
At least some older implementations don't have
|
||||
<command>std::ios_base</command>, so you should use
|
||||
<command>std::ios::badbit</command>, <command>std::ios::failbit</command>
|
||||
and <command>std::ios::eofbit</command> and
|
||||
<command>std::ios::goodbit</command>.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="sec-vector-at" label="8">
|
||||
<title>vector::at is missing (i.e. gcc 2.95.x)</title>
|
||||
<para>
|
||||
One solution is to add an autoconf-test for this:
|
||||
<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)])
|
||||
</programlisting>
|
||||
If you are using other (non-GNU) compilers it might be a good idea
|
||||
to check for <command>string::at</command> separately.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="sec-eof" label="9">
|
||||
<title>Using std::char_traits<char>::eof()</title>
|
||||
<para>
|
||||
<programlisting>
|
||||
#ifdef HAVE_CHAR_TRAITS
|
||||
#define CPP_EOF std::char_traits<char>::eof()
|
||||
#else
|
||||
#define CPP_EOF EOF
|
||||
#endif
|
||||
</programlisting>
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="sec-string-clear" label="10">
|
||||
<title>Using string::clear()/string::erase()</title>
|
||||
<para>
|
||||
There are two functions for deleting the contents of a string:
|
||||
<command>clear</command> and <command>erase</command> (the latter
|
||||
returns the string).
|
||||
<programlisting>
|
||||
void
|
||||
clear() { _M_mutate(0, this->size(), 0); }
|
||||
</programlisting>
|
||||
<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());
|
||||
}
|
||||
</programlisting>
|
||||
The implementation of <command>erase</command> seems to be more
|
||||
complicated (from libstdc++-v3), but <command>clear</command> is not
|
||||
implemented in gcc 2.95.x's libstdc++, so you should use
|
||||
<command>erase</command> (which is probably faster than
|
||||
<command>operator=(charT*)</command>).
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="sec-scan-form" label="11">
|
||||
<title>GNU Extensions ostream::form and istream::scan</title>
|
||||
<para>
|
||||
These are not supported any more - use
|
||||
<link linkend="sec-stringstream" endterm="sec-stringstream.title">
|
||||
stringstreams</link> instead.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id="sec-stringstream" label="12">
|
||||
<title>Using stringstreams</title>
|
||||
<para>
|
||||
Libstdc++-v3 provides the new
|
||||
<command>i/ostringstream</command>-classes, (<filename
|
||||
class="headerfile"><sstream></filename>), but for compatibility
|
||||
with older implementations you still have to use
|
||||
<command>i/ostrstream</command> (<filename
|
||||
class="headerfile"><strstream></filename>):
|
||||
<programlisting>
|
||||
#ifdef HAVE_SSTREAM
|
||||
#include <sstream>
|
||||
#else
|
||||
#include <strstream>
|
||||
#endif
|
||||
</programlisting>
|
||||
<itemizedlist>
|
||||
<listitem><para> <command>strstream</command> is considered to be
|
||||
deprecated
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem><para> <command>strstream</command> is limited to
|
||||
<command>char</command>
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem><para> with <command>ostringstream</command> you don't
|
||||
have to take care of terminating the string or freeing its
|
||||
memory
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem><para> <command>istringstream</command> can be re-filled
|
||||
(clear(); str(input);)
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
<para>
|
||||
You can then use output-stringstreams like this:
|
||||
<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
|
||||
</programlisting>
|
||||
</para>
|
||||
<para>
|
||||
Input-stringstreams can be used similarly:
|
||||
<programlisting>
|
||||
std::string input;
|
||||
...
|
||||
#ifdef HAVE_SSTREAM
|
||||
std::istringstream iss(input);
|
||||
#else
|
||||
std::istrstream iss(input.c_str());
|
||||
#endif
|
||||
int i;
|
||||
iss >> i;
|
||||
</programlisting>
|
||||
One (the only?) restriction is that an istrstream cannot be re-filled:
|
||||
<programlisting>
|
||||
std::istringstream iss(numerator);
|
||||
iss >> m_num;
|
||||
// this is not possible with istrstream
|
||||
iss.clear();
|
||||
iss.str(denominator);
|
||||
iss >> m_den;
|
||||
</programlisting>
|
||||
If you don't care about speed, you can put these conversions in
|
||||
a template-function:
|
||||
<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;
|
||||
}
|
||||
</programlisting>
|
||||
Another example of using stringstreams is in <ulink
|
||||
url="../21_strings/howto.html">this howto</ulink>.
|
||||
</para>
|
||||
<para>
|
||||
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.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
<section id = "sec-about" label="13">
|
||||
<title id="sec-about.title">About...</title>
|
||||
<para>
|
||||
Please send any experience, additions, corrections or questions to
|
||||
<ulink url = "mailto:fnatter@gmx.net">fnatter@gmx.net</ulink> or for
|
||||
discussion to the libstdc++-v3-mailing-list.
|
||||
</para>
|
||||
</section>
|
||||
|
||||
</article>
|
||||
|
||||
<!-- this is now obsolete, since the nwalsh-stylesheet generates an index
|
||||
<para>
|
||||
<itemizedlist>
|
||||
<listitem><para>
|
||||
<link linkend = "sec-nsstd" endterm = "sec-nsstd.title"/>
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<link linkend = "sec-nocreate" endterm = "sec-nocreate.title"/>
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<link linkend = "sec-stream::attach"
|
||||
endterm = "sec-stream::attach.title"/>
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<link linkend = "sec-headers" endterm = "sec-headers.title"/>
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<link linkend = "sec-iterators" endterm = "sec-iterators.title"/>
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<link linkend = "sec-macros" endterm = "sec-macros.title"/>
|
||||
</para></listitem>
|
||||
<listitem><para>
|
||||
<link linkend = "sec-about" endterm = "sec-about.title"/>
|
||||
</para></listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
-->
|
||||
|
||||
<!--
|
||||
Local Variables:
|
||||
compile-command: "xsltproc -o porting-howto.html docbook-xslt/docbook/html/docbook.xsl porting-howto.xml"
|
||||
End:
|
||||
-->
|
Loading…
Reference in New Issue
Block a user