1 |
20 |
jlechner |
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
|
2 |
|
|
<html>
|
3 |
|
|
<head>
|
4 |
|
|
<meta content="text/html; charset=ISO-8859-1" http-equiv="Content-Type">
|
5 |
|
|
<title>Libstdc++-porting-howto</title>
|
6 |
|
|
<meta name="generator" content="DocBook XSL Stylesheets V1.48">
|
7 |
|
|
</head>
|
8 |
|
|
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="article">
|
9 |
|
|
<div class="titlepage">
|
10 |
|
|
<div><h1 class="title">
|
11 |
|
|
<a name="libstdc++-porting-howto"></a>Libstdc++-porting-howto</h1></div>
|
12 |
|
|
<div><h3 class="author">Felix Natter</h3></div>
|
13 |
|
|
<div><div class="legalnotice">
|
14 |
|
|
<p class="legalnotice-title"><b>Legal Notice</b></p>
|
15 |
|
|
<p>
|
16 |
|
|
This document can be distributed under the FDL
|
17 |
|
|
(<a href="http://www.gnu.org" target="_top">www.gnu.org</a>)
|
18 |
|
|
</p>
|
19 |
|
|
</div></div>
|
20 |
|
|
<div><p class="pubdate">Tue Jun 5 20:07:49 2001</p></div>
|
21 |
|
|
<div><div class="revhistory"><table border="1" width="100%" summary="Revision history">
|
22 |
|
|
<tr><th align="left" valign="top" colspan="3"><b>Revision History</b></th></tr>
|
23 |
|
|
<tr>
|
24 |
|
|
<td align="left">Revision 0.5</td>
|
25 |
|
|
<td align="left">Thu Jun 1 13:06:50 2000</td>
|
26 |
|
|
<td align="left">fnatter</td>
|
27 |
|
|
</tr>
|
28 |
|
|
<tr><td align="left" colspan="3">First docbook-version.</td></tr>
|
29 |
|
|
<tr>
|
30 |
|
|
<td align="left">Revision 0.8</td>
|
31 |
|
|
<td align="left">Sun Jul 30 20:28:40 2000</td>
|
32 |
|
|
<td align="left">fnatter</td>
|
33 |
|
|
</tr>
|
34 |
|
|
<tr><td align="left" colspan="3">First released version using docbook-xml
|
35 |
|
|
+ second upload to libstdc++-page.
|
36 |
|
|
</td></tr>
|
37 |
|
|
<tr>
|
38 |
|
|
<td align="left">Revision 0.9</td>
|
39 |
|
|
<td align="left">Wed Sep 6 02:59:32 2000</td>
|
40 |
|
|
<td align="left">fnatter</td>
|
41 |
|
|
</tr>
|
42 |
|
|
<tr><td align="left" colspan="3">5 new sections.</td></tr>
|
43 |
|
|
<tr>
|
44 |
|
|
<td align="left">Revision 0.9.1</td>
|
45 |
|
|
<td align="left">Sat Sep 23 14:20:15 2000</td>
|
46 |
|
|
<td align="left">fnatter</td>
|
47 |
|
|
</tr>
|
48 |
|
|
<tr><td align="left" colspan="3">added information about why file-descriptors are not in the
|
49 |
|
|
standard</td></tr>
|
50 |
|
|
<tr>
|
51 |
|
|
<td align="left">Revision 0.9.2</td>
|
52 |
|
|
<td align="left">Tue Jun 5 20:07:49 2001</td>
|
53 |
|
|
<td align="left">fnatter</td>
|
54 |
|
|
</tr>
|
55 |
|
|
<tr><td align="left" colspan="3">
|
56 |
|
|
a fix, added hint on increased portability of C-shadow-headers,
|
57 |
|
|
added autoconf-test HAVE_CONTAINER_AT
|
58 |
|
|
</td></tr>
|
59 |
|
|
<tr>
|
60 |
|
|
<td align="left">Revision 0.9.3</td>
|
61 |
|
|
<td align="left">Fri Jun 29 16:15:56 2001</td>
|
62 |
|
|
<td align="left">fnatter</td>
|
63 |
|
|
</tr>
|
64 |
|
|
<tr><td align="left" colspan="3">
|
65 |
|
|
changed signature of nonstandard filebuf-constructor and
|
66 |
|
|
update the section on filebuf::attach to point to ../ext/howto.html,
|
67 |
|
|
added link to ../21/strings/howto.html
|
68 |
|
|
in sec-stringstream, changed <link>-tags to have content
|
69 |
|
|
(so that these links work),
|
70 |
|
|
replace "user-space" by "global namespace"
|
71 |
|
|
add note about gcc 3.0 and shadow-headers
|
72 |
|
|
add section about ostream::form and istream::scan
|
73 |
|
|
sec-vector-at: remove hint to modify headers
|
74 |
|
|
fix spelling error in sec-stringstream
|
75 |
|
|
</td></tr>
|
76 |
|
|
<tr>
|
77 |
|
|
<td align="left">Revision 0.9.4</td>
|
78 |
|
|
<td align="left">Mon Nov 5 17:01:04 2001</td>
|
79 |
|
|
<td align="left">fnatter</td>
|
80 |
|
|
</tr>
|
81 |
|
|
<tr><td align="left" colspan="3">
|
82 |
|
|
rewrite section 1.1.3 because of gnu.gcc.help-post by
|
83 |
|
|
Juergen Heinzl
|
84 |
|
|
</td></tr>
|
85 |
|
|
</table></div></div>
|
86 |
|
|
<div><div class="abstract">
|
87 |
|
|
<p><b>Abstract</b></p>
|
88 |
|
|
<p>
|
89 |
|
|
Some notes on porting applications from libstdc++-2.90 (or earlier
|
90 |
|
|
versions) to libstdc++-v3. Not speaking in terms of the GNU libstdc++
|
91 |
|
|
implementations, this means porting from earlier versions of the
|
92 |
|
|
C++-Standard to ISO 14882.
|
93 |
|
|
</p>
|
94 |
|
|
</div></div>
|
95 |
|
|
<hr>
|
96 |
|
|
</div>
|
97 |
|
|
<div class="toc">
|
98 |
|
|
<p><b>Table of Contents</b></p>
|
99 |
|
|
<dl>
|
100 |
|
|
<dt>1. <a href="#sec-nsstd">Namespace std::</a>
|
101 |
|
|
</dt>
|
102 |
|
|
<dd><dl>
|
103 |
|
|
<dt>1.1.1. <a href="#sec-gtkmm-hack">Using namespace
|
104 |
|
|
composition if the project uses a separate
|
105 |
|
|
namespace</a>
|
106 |
|
|
</dt>
|
107 |
|
|
<dt>1.1.2. <a href="#sec-emptyns">Defining an empty namespace std</a>
|
108 |
|
|
</dt>
|
109 |
|
|
<dt>1.1.3. <a href="#sec-avoidfqn">Avoid to use fully qualified names
|
110 |
|
|
(i.e. std::string)</a>
|
111 |
|
|
</dt>
|
112 |
|
|
<dt>1.1.4. <a href="#sec-osprojects">How some open-source-projects deal
|
113 |
|
|
with this</a>
|
114 |
|
|
</dt>
|
115 |
|
|
</dl></dd>
|
116 |
|
|
<dt>2. <a href="#sec-nocreate">there is no ios::nocreate/ios::noreplace
|
117 |
|
|
in ISO 14882</a>
|
118 |
|
|
</dt>
|
119 |
|
|
<dt>3. <a href="#sec-stream::attach">stream::attach(int
|
120 |
|
|
fd) is not in the standard any more</a>
|
121 |
|
|
</dt>
|
122 |
|
|
<dt>4. <a href="#sec-headers">The new headers</a>
|
123 |
|
|
</dt>
|
124 |
|
|
<dd><dl>
|
125 |
|
|
<dt>4.4.1. <a href="#sec-cheaders">New headers replacing C-headers</a>
|
126 |
|
|
</dt>
|
127 |
|
|
<dt>4.4.2. <a href="#sec-fstream-header">
|
128 |
|
|
<fstream> does
|
129 |
|
|
not define std::cout,
|
130 |
|
|
std::cin etc.</a>
|
131 |
|
|
</dt>
|
132 |
|
|
</dl></dd>
|
133 |
|
|
<dt>5. <a href="#sec-iterators">Iterators</a>
|
134 |
|
|
</dt>
|
135 |
|
|
<dt>6. <a href="#sec-macros">
|
136 |
|
|
Libc-macros (i.e. isspace from
|
137 |
|
|
<cctype>)</a>
|
138 |
|
|
</dt>
|
139 |
|
|
<dt>7. <a href="#sec-stream-state">State of streams</a>
|
140 |
|
|
</dt>
|
141 |
|
|
<dt>8. <a href="#sec-vector-at">vector::at is missing (i.e. gcc 2.95.x)</a>
|
142 |
|
|
</dt>
|
143 |
|
|
<dt>9. <a href="#sec-eof">Using std::char_traits<char>::eof()</a>
|
144 |
|
|
</dt>
|
145 |
|
|
<dt>10. <a href="#sec-string-clear">Using string::clear()/string::erase()</a>
|
146 |
|
|
</dt>
|
147 |
|
|
<dt>11. <a href="#sec-scan-form">GNU Extensions ostream::form and istream::scan</a>
|
148 |
|
|
</dt>
|
149 |
|
|
<dt>12. <a href="#sec-stringstream">Using stringstreams</a>
|
150 |
|
|
</dt>
|
151 |
|
|
<dt>13. <a href="#sec-about">About...</a>
|
152 |
|
|
</dt>
|
153 |
|
|
</dl>
|
154 |
|
|
</div>
|
155 |
|
|
<p>
|
156 |
|
|
In the following, when I say portable, I will refer to "portable among ISO
|
157 |
|
|
14882-implementations". On the other hand, if I say "backportable" or
|
158 |
|
|
"conservative", I am talking about "compiles with older
|
159 |
|
|
libstdc++-implementations".
|
160 |
|
|
</p>
|
161 |
|
|
<div class="section">
|
162 |
|
|
<div class="titlepage"><div><h2 class="title" style="clear: both">
|
163 |
|
|
<a name="sec-nsstd"></a>Namespace std::</h2></div></div>
|
164 |
|
|
<p>
|
165 |
|
|
The latest C++-standard (ISO-14882) requires that the standard
|
166 |
|
|
C++-library is defined in namespace std::. Thus, in order to use
|
167 |
|
|
classes from the standard C++-library, you can do one of three
|
168 |
|
|
things:
|
169 |
|
|
<div class="itemizedlist"><ul type="disc">
|
170 |
|
|
<li><p>wrap your code in <b>namespace std {
|
171 |
|
|
... }</b> => This is not an option because only symbols
|
172 |
|
|
from the standard c++-library are defined in namespace std::.
|
173 |
|
|
</p></li>
|
174 |
|
|
<li><p>put a kind of
|
175 |
|
|
<span class="emphasis"><i>using-declaration</i></span> in your source (either
|
176 |
|
|
<b>using namespace std;</b> or i.e. <b>using
|
177 |
|
|
std::string;</b>) => works well for source-files, but
|
178 |
|
|
cannot be used in header-files.
|
179 |
|
|
</p></li>
|
180 |
|
|
<li><p>use a <span class="emphasis"><i>fully qualified name</i></span> for
|
181 |
|
|
each libstdc++-symbol (i.e. <b>std::string</b>,
|
182 |
|
|
<b>std::cout</b>) => can always be used
|
183 |
|
|
</p></li>
|
184 |
|
|
</ul></div>
|
185 |
|
|
</p>
|
186 |
|
|
<p>
|
187 |
|
|
Because there are many compilers which still use an implementation
|
188 |
|
|
that does not have the standard C++-library in namespace
|
189 |
|
|
<b>std::</b>, some care is required to support these as
|
190 |
|
|
well.
|
191 |
|
|
</p>
|
192 |
|
|
<p>
|
193 |
|
|
Namespace back-portability-issues are generally not a problem with
|
194 |
|
|
g++, because versions of g++ that do not have libstdc++ in
|
195 |
|
|
<b>std::</b> use <b>-fno-honor-std</b>
|
196 |
|
|
(ignore <b>std::</b>, <b>:: = std::</b>) by
|
197 |
|
|
default. That is, the responsibility for enabling or disabling
|
198 |
|
|
<b>std::</b> is on the user; the maintainer does not have
|
199 |
|
|
to care about it. This probably applies to some other compilers as
|
200 |
|
|
well.
|
201 |
|
|
</p>
|
202 |
|
|
<p>
|
203 |
|
|
The following sections list some possible solutions to support compilers
|
204 |
|
|
that cannot ignore std::.
|
205 |
|
|
</p>
|
206 |
|
|
<div class="section">
|
207 |
|
|
<div class="titlepage"><div><h3 class="title">
|
208 |
|
|
<a name="sec-gtkmm-hack"></a>Using <span class="emphasis"><i>namespace
|
209 |
|
|
composition</i></span> if the project uses a separate
|
210 |
|
|
namespace</h3></div></div>
|
211 |
|
|
<p>
|
212 |
|
|
<a href="http://gtkmm.sourceforge.net" target="_top">Gtk--</a> defines
|
213 |
|
|
most of its classes in namespace Gtk::. Thus, it was possible to
|
214 |
|
|
adapt Gtk-- to namespace std:: by using a C++-feature called
|
215 |
|
|
<span class="emphasis"><i>namespace composition</i></span>. This is what happens if
|
216 |
|
|
you put a <span class="emphasis"><i>using</i></span>-declaration into a
|
217 |
|
|
namespace-definition: the imported symbol(s) gets imported into the
|
218 |
|
|
currently active namespace(s). For example:
|
219 |
|
|
<pre class="programlisting">
|
220 |
|
|
namespace Gtk {
|
221 |
|
|
using std::string;
|
222 |
|
|
class Window { ... }
|
223 |
|
|
}
|
224 |
|
|
</pre>
|
225 |
|
|
In this example, <b>std::string</b> gets imported into
|
226 |
|
|
namespace Gtk::. The result is that you don't have to use
|
227 |
|
|
<b>std::string</b> in this header, but still
|
228 |
|
|
<b>std::string</b> does not get imported into
|
229 |
|
|
the global namespace (::) unless the user does
|
230 |
|
|
<b>using namespace Gtk;</b> (which is not recommended
|
231 |
|
|
practice for Gtk--, so it is not a problem). Additionally, the
|
232 |
|
|
<b>using</b>-declarations are wrapped in macros that
|
233 |
|
|
are set based on autoconf-tests to either "" or i.e. <b>using
|
234 |
|
|
std::string;</b> (depending on whether the system has
|
235 |
|
|
libstdc++ in <b>std::</b> or not). (ideas from
|
236 |
|
|
<tt><<a href="mailto:llewelly@dbritsch.dsl.xmission.com">llewelly@dbritsch.dsl.xmission.com</a>></tt>, Karl Nelson
|
237 |
|
|
<tt><<a href="mailto:kenelson@ece.ucdavis.edu">kenelson@ece.ucdavis.edu</a>></tt>)
|
238 |
|
|
</p>
|
239 |
|
|
</div>
|
240 |
|
|
<div class="section">
|
241 |
|
|
<div class="titlepage"><div><h3 class="title">
|
242 |
|
|
<a name="sec-emptyns"></a>Defining an empty namespace std</h3></div></div>
|
243 |
|
|
<p>
|
244 |
|
|
By defining an (empty) namespace <b>std::</b> before
|
245 |
|
|
using it, you avoid getting errors on systems where no part of the
|
246 |
|
|
library is in namespace std:
|
247 |
|
|
<pre class="programlisting">
|
248 |
|
|
namespace std { }
|
249 |
|
|
using namespace std;
|
250 |
|
|
</pre>
|
251 |
|
|
</p>
|
252 |
|
|
</div>
|
253 |
|
|
<div class="section">
|
254 |
|
|
<div class="titlepage"><div><h3 class="title">
|
255 |
|
|
<a name="sec-avoidfqn"></a>Avoid to use fully qualified names
|
256 |
|
|
(i.e. std::string)</h3></div></div>
|
257 |
|
|
<p>
|
258 |
|
|
If some compilers complain about <b>using
|
259 |
|
|
std::string;</b>, and if the "hack" for gtk-- mentioned above
|
260 |
|
|
does not work, then I see two solutions:
|
261 |
|
|
|
262 |
|
|
<div class="itemizedlist"><ul type="disc">
|
263 |
|
|
<li><p>
|
264 |
|
|
Define <b>std::</b> as a macro if the compiler
|
265 |
|
|
doesn't know about <b>std::</b>.
|
266 |
|
|
<pre class="programlisting">
|
267 |
|
|
#ifdef OLD_COMPILER
|
268 |
|
|
#define std
|
269 |
|
|
#endif
|
270 |
|
|
</pre>
|
271 |
|
|
(thanks to Juergen Heinzl who posted this solution on
|
272 |
|
|
gnu.gcc.help)
|
273 |
|
|
</p></li>
|
274 |
|
|
<li><p>
|
275 |
|
|
Define a macro NS_STD, which is defined to
|
276 |
|
|
either "" or "std"
|
277 |
|
|
based on an autoconf-test. Then you should be able to use
|
278 |
|
|
<b>NS_STD::string</b>, which will evaluate to
|
279 |
|
|
<b>::string</b> ("string in the global namespace") on
|
280 |
|
|
systems that do not put string in std::. (This is untested)
|
281 |
|
|
</p></li>
|
282 |
|
|
</ul></div>
|
283 |
|
|
|
284 |
|
|
</p>
|
285 |
|
|
</div>
|
286 |
|
|
<div class="section">
|
287 |
|
|
<div class="titlepage"><div><h3 class="title">
|
288 |
|
|
<a name="sec-osprojects"></a>How some open-source-projects deal
|
289 |
|
|
with this</h3></div></div>
|
290 |
|
|
<p>
|
291 |
|
|
This information was gathered around May 2000. It may not be correct
|
292 |
|
|
by the time you read this.
|
293 |
|
|
</p>
|
294 |
|
|
<div class="table">
|
295 |
|
|
<p><b>Table 1. Namespace std:: in Open-Source programs</b></p>
|
296 |
|
|
<table summary="Namespace std:: in Open-Source programs" border="1">
|
297 |
|
|
<colgroup>
|
298 |
|
|
<col>
|
299 |
|
|
<col>
|
300 |
|
|
</colgroup>
|
301 |
|
|
<tbody>
|
302 |
|
|
<tr>
|
303 |
|
|
<td><a href="http://www.clanlib.org" target="_top">clanlib</a></td>
|
304 |
|
|
<td>usual</td>
|
305 |
|
|
</tr>
|
306 |
|
|
<tr>
|
307 |
|
|
<td><a href="http://pingus.seul.org" target="_top">pingus</a></td>
|
308 |
|
|
<td>usual</td>
|
309 |
|
|
</tr>
|
310 |
|
|
<tr>
|
311 |
|
|
<td><a href="http://www.mozilla.org" target="_top">mozilla</a></td>
|
312 |
|
|
<td>usual</td>
|
313 |
|
|
</tr>
|
314 |
|
|
<tr>
|
315 |
|
|
<td><a href="http://libsigc.sourceforge.net" target="_top">
|
316 |
|
|
libsigc++</a></td>
|
317 |
|
|
<td>conservative-impl</td>
|
318 |
|
|
</tr>
|
319 |
|
|
</tbody>
|
320 |
|
|
</table>
|
321 |
|
|
</div>
|
322 |
|
|
<div class="table">
|
323 |
|
|
<p><b>Table 2. Notations for categories</b></p>
|
324 |
|
|
<table summary="Notations for categories" border="1">
|
325 |
|
|
<colgroup>
|
326 |
|
|
<col>
|
327 |
|
|
<col>
|
328 |
|
|
</colgroup>
|
329 |
|
|
<tbody>
|
330 |
|
|
<tr>
|
331 |
|
|
<td>usual</td>
|
332 |
|
|
<td>mostly fully qualified names and some
|
333 |
|
|
using-declarations (but not in headers)</td>
|
334 |
|
|
</tr>
|
335 |
|
|
<tr>
|
336 |
|
|
<td>none</td>
|
337 |
|
|
<td>no namespace std at all</td>
|
338 |
|
|
</tr>
|
339 |
|
|
<tr>
|
340 |
|
|
<td>conservative-impl</td>
|
341 |
|
|
<td>wrap all
|
342 |
|
|
namespace-handling in macros to support compilers without
|
343 |
|
|
namespace-support (no libstdc++ used in headers)</td>
|
344 |
|
|
</tr>
|
345 |
|
|
</tbody>
|
346 |
|
|
</table>
|
347 |
|
|
</div>
|
348 |
|
|
<p>
|
349 |
|
|
As you can see, this currently lacks an example of a project
|
350 |
|
|
which uses libstdc++-symbols in headers in a back-portable way
|
351 |
|
|
(except for Gtk--: see the <a href="#sec-gtkmm-hack" title="Using namespace
|
352 |
|
|
composition if the project uses a separate
|
353 |
|
|
namespace">section on the gtkmm-hack</a>).
|
354 |
|
|
</p>
|
355 |
|
|
</div>
|
356 |
|
|
</div>
|
357 |
|
|
<div class="section">
|
358 |
|
|
<div class="titlepage"><div><h2 class="title" style="clear: both">
|
359 |
|
|
<a name="sec-nocreate"></a>there is no ios::nocreate/ios::noreplace
|
360 |
|
|
in ISO 14882</h2></div></div>
|
361 |
|
|
<p>
|
362 |
|
|
I have seen <b>ios::nocreate</b> being used for
|
363 |
|
|
input-streams, most probably because the author thought it would be
|
364 |
|
|
more correct to specify nocreate "explicitly". So you can simply
|
365 |
|
|
leave it out for input-streams.
|
366 |
|
|
</p>
|
367 |
|
|
<p>
|
368 |
|
|
For output streams, "nocreate" is probably the default, unless you
|
369 |
|
|
specify <b>std::ios::trunc</b> ? To be safe, you can open
|
370 |
|
|
the file for reading, check if it has been opened, and then decide
|
371 |
|
|
whether you want to create/replace or not. To my knowledge, even
|
372 |
|
|
older implementations support <b>app</b>,
|
373 |
|
|
<b>ate</b> and <b>trunc</b> (except for
|
374 |
|
|
<b>app</b> ?).
|
375 |
|
|
</p>
|
376 |
|
|
</div>
|
377 |
|
|
<div class="section">
|
378 |
|
|
<div class="titlepage"><div><h2 class="title" style="clear: both">
|
379 |
|
|
<a name="sec-stream::attach"></a><b>stream::attach(int
|
380 |
|
|
fd)</b> is not in the standard any more</h2></div></div>
|
381 |
|
|
<p>
|
382 |
|
|
Phil Edwards <tt><<a href="mailto:pedwards@disaster.jaj.com">pedwards@disaster.jaj.com</a>></tt> writes:
|
383 |
|
|
It was considered and rejected. Not all environments use file
|
384 |
|
|
descriptors. Of those that do, not all of them use integers to represent
|
385 |
|
|
them.
|
386 |
|
|
</p>
|
387 |
|
|
<p>
|
388 |
|
|
When using libstdc++-v3, you can use
|
389 |
|
|
<div class="funcsynopsis">
|
390 |
|
|
<pre class="funcsynopsisinfo">
|
391 |
|
|
#include <fstream>
|
392 |
|
|
</pre>
|
393 |
|
|
<p><code><code class="funcdef">
|
394 |
|
|
<b class="fsfunc">basic_filebuf<...>::basic_filebuf<...>
|
395 |
|
|
</b>
|
396 |
|
|
</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>
|
397 |
|
|
</div>
|
398 |
|
|
but the the signature of this constructor has changed often, and
|
399 |
|
|
it might change again. For the current state of this, check
|
400 |
|
|
<a href="../ext/howto.html" target="_top">the howto for extensions</a>.
|
401 |
|
|
</p>
|
402 |
|
|
<p>
|
403 |
|
|
For a portable solution (among systems which use
|
404 |
|
|
filedescriptors), you need to implement a subclass of
|
405 |
|
|
<b>std::streambuf</b> (or
|
406 |
|
|
<b>std::basic_streambuf<..></b>) which opens a file
|
407 |
|
|
given a descriptor, and then pass an instance of this to the
|
408 |
|
|
stream-constructor. For an example of this, refer to
|
409 |
|
|
<a href="http://www.josuttis.com/cppcode/fdstream.html" target="_top">fdstream example</a>
|
410 |
|
|
by Nicolai Josuttis.
|
411 |
|
|
</p>
|
412 |
|
|
</div>
|
413 |
|
|
<div class="section">
|
414 |
|
|
<div class="titlepage"><div><h2 class="title" style="clear: both">
|
415 |
|
|
<a name="sec-headers"></a>The new headers</h2></div></div>
|
416 |
|
|
<p>
|
417 |
|
|
All new headers can be seen in this <a href="headers_cc.txt" target="_top">
|
418 |
|
|
source-code</a>.
|
419 |
|
|
</p>
|
420 |
|
|
<p>
|
421 |
|
|
The old C++-headers (iostream.h etc.) are available, but gcc generates
|
422 |
|
|
a warning that you are using deprecated headers.
|
423 |
|
|
</p>
|
424 |
|
|
<div class="section">
|
425 |
|
|
<div class="titlepage"><div><h3 class="title">
|
426 |
|
|
<a name="sec-cheaders"></a>New headers replacing C-headers</h3></div></div>
|
427 |
|
|
<p>
|
428 |
|
|
You should not use the C-headers (except for system-level
|
429 |
|
|
headers) from C++ programs. Instead, you should use a set of
|
430 |
|
|
headers that are named by prepending 'c' and, as usual,
|
431 |
|
|
omitting the extension (.h). For example, instead of using
|
432 |
|
|
<tt><math.h></tt>, you
|
433 |
|
|
should use <tt><cmath></tt>. In some cases this has
|
434 |
|
|
the advantage that the C++-header is more standardized than
|
435 |
|
|
the C-header (i.e. <tt><ctime></tt> (almost)
|
436 |
|
|
corresponds to either <tt><time.h></tt> or <tt><sys/time.h></tt>).
|
437 |
|
|
|
438 |
|
|
The standard specifies that if you include the C-style header
|
439 |
|
|
(<tt><math.h></tt> in
|
440 |
|
|
this case), the symbols will be available both in the global
|
441 |
|
|
namespace and in namespace <b>std::</b> (but
|
442 |
|
|
libstdc++ does not yet have fully compliant headers) On the
|
443 |
|
|
other hand, if you include only the new header (i.e. <tt><cmath></tt>), the symbols
|
444 |
|
|
will only be defined in namespace <b>std::</b>
|
445 |
|
|
(and macros will be converted to inline-functions).
|
446 |
|
|
</p>
|
447 |
|
|
<p>
|
448 |
|
|
For more information on this, and for information on how the
|
449 |
|
|
GNU C++ implementation might reuse ("shadow") the C
|
450 |
|
|
library-functions, have a look at <a href="http://www.cantrip.org/cheaders.html" target="_top">
|
451 |
|
|
www.cantrip.org</a>.
|
452 |
|
|
</p>
|
453 |
|
|
</div>
|
454 |
|
|
<div class="section">
|
455 |
|
|
<div class="titlepage"><div><h3 class="title">
|
456 |
|
|
<a name="sec-fstream-header"></a>
|
457 |
|
|
<tt><fstream></tt> does
|
458 |
|
|
not define <b>std::cout</b>,
|
459 |
|
|
<b>std::cin</b> etc.</h3></div></div>
|
460 |
|
|
<p>
|
461 |
|
|
In earlier versions of the standard,
|
462 |
|
|
<tt><fstream.h></tt>,
|
463 |
|
|
<tt><ostream.h></tt>
|
464 |
|
|
and <tt><istream.h></tt>
|
465 |
|
|
used to define
|
466 |
|
|
<b>cout</b>, <b>cin</b> and so on. Because
|
467 |
|
|
of the templatized iostreams in libstdc++-v3, you need to include
|
468 |
|
|
<tt><iostream></tt>
|
469 |
|
|
explicitly to define these.
|
470 |
|
|
</p>
|
471 |
|
|
</div>
|
472 |
|
|
</div>
|
473 |
|
|
<div class="section">
|
474 |
|
|
<div class="titlepage"><div><h2 class="title" style="clear: both">
|
475 |
|
|
<a name="sec-iterators"></a>Iterators</h2></div></div>
|
476 |
|
|
<p>
|
477 |
|
|
The following are not proper uses of iterators, but may be working
|
478 |
|
|
fixes for existing uses of iterators.
|
479 |
|
|
<div class="itemizedlist"><ul type="disc">
|
480 |
|
|
<li><p>you cannot do
|
481 |
|
|
<b>ostream::operator<<(iterator)</b> to
|
482 |
|
|
print the address of the iterator => use
|
483 |
|
|
<b>operator<< &*iterator</b> instead ?
|
484 |
|
|
</p></li>
|
485 |
|
|
<li><p>you cannot clear an iterator's reference
|
486 |
|
|
(<b>iterator = 0</b>) => use
|
487 |
|
|
<b>iterator = iterator_type();</b> ?
|
488 |
|
|
</p></li>
|
489 |
|
|
<li><p>
|
490 |
|
|
<b>if (iterator)</b> won't work any
|
491 |
|
|
more => use <b>if (iterator != iterator_type())</b>
|
492 |
|
|
?</p></li>
|
493 |
|
|
</ul></div>
|
494 |
|
|
</p>
|
495 |
|
|
</div>
|
496 |
|
|
<div class="section">
|
497 |
|
|
<div class="titlepage"><div><h2 class="title" style="clear: both">
|
498 |
|
|
<a name="sec-macros"></a>
|
499 |
|
|
Libc-macros (i.e. <b>isspace</b> from
|
500 |
|
|
<tt><cctype></tt>)</h2></div></div>
|
501 |
|
|
<p>
|
502 |
|
|
Glibc 2.0.x and 2.1.x define the
|
503 |
|
|
<tt><ctype.h></tt>
|
504 |
|
|
-functionality as macros (isspace, isalpha etc.). Libstdc++-v3
|
505 |
|
|
"shadows" these macros as described in the <a href="#sec-cheaders" title="New headers replacing C-headers">section about
|
506 |
|
|
c-headers</a>.
|
507 |
|
|
</p>
|
508 |
|
|
<p>
|
509 |
|
|
Older implementations of libstdc++ (g++-2 for egcs 1.x and g++-3
|
510 |
|
|
for gcc 2.95.x), however, keep these functions as macros, and so it
|
511 |
|
|
is not back-portable to use fully qualified names. For example:
|
512 |
|
|
<pre class="programlisting">
|
513 |
|
|
#include <cctype>
|
514 |
|
|
int main() { std::isspace('X'); }
|
515 |
|
|
</pre>
|
516 |
|
|
will result in something like this (unless using g++-v3):
|
517 |
|
|
<pre class="programlisting">
|
518 |
|
|
std:: (__ctype_b[(int) ( ( 'X' ) )] & (unsigned short int)
|
519 |
|
|
_ISspace ) ;
|
520 |
|
|
</pre>
|
521 |
|
|
</p>
|
522 |
|
|
<p>
|
523 |
|
|
One solution I can think of is to test for -v3 using
|
524 |
|
|
autoconf-macros, and define macros for each of the C-functions
|
525 |
|
|
(maybe that is possible with one "wrapper" macro as well ?).
|
526 |
|
|
</p>
|
527 |
|
|
<p>
|
528 |
|
|
Another solution which would fix g++ is to tell the user to modify a
|
529 |
|
|
header-file so that g++-2 (egcs 1.x) and g++-3 (gcc 2.95.x) define a
|
530 |
|
|
macro which tells <tt><ctype.h></tt> to define functions
|
531 |
|
|
instead of macros:
|
532 |
|
|
<pre class="programlisting">
|
533 |
|
|
// This keeps isalnum, et al from being propagated as macros.
|
534 |
|
|
#if __linux__
|
535 |
|
|
#define __NO_CTYPE 1
|
536 |
|
|
#endif
|
537 |
|
|
|
538 |
|
|
[ now include <ctype.h> ]
|
539 |
|
|
</pre>
|
540 |
|
|
</p>
|
541 |
|
|
<p>
|
542 |
|
|
Another problem arises if you put a <b>using namespace
|
543 |
|
|
std;</b> declaration at the top, and include <tt><ctype.h></tt>. This will result in
|
544 |
|
|
ambiguities between the definitions in the global namespace
|
545 |
|
|
(<tt><ctype.h></tt>) and the
|
546 |
|
|
definitions in namespace <b>std::</b>
|
547 |
|
|
(<b><cctype></b>).
|
548 |
|
|
</p>
|
549 |
|
|
<p>
|
550 |
|
|
The solution to this problem was posted to the libstdc++-v3
|
551 |
|
|
mailing-list:
|
552 |
|
|
Benjamin Kosnik <tt><<a href="mailto:bkoz@redhat.com">bkoz@redhat.com</a>></tt> writes:
|
553 |
|
|
‘
|
554 |
|
|
--enable-cshadow-headers is currently broken. As a result, shadow
|
555 |
|
|
headers are not being searched....
|
556 |
|
|
’
|
557 |
|
|
This is now outdated, but gcc 3.0 still does not have fully
|
558 |
|
|
compliant "shadow headers".
|
559 |
|
|
</p>
|
560 |
|
|
</div>
|
561 |
|
|
<div class="section">
|
562 |
|
|
<div class="titlepage"><div><h2 class="title" style="clear: both">
|
563 |
|
|
<a name="sec-stream-state"></a>State of streams</h2></div></div>
|
564 |
|
|
<p>
|
565 |
|
|
At least some older implementations don't have
|
566 |
|
|
<b>std::ios_base</b>, so you should use
|
567 |
|
|
<b>std::ios::badbit</b>, <b>std::ios::failbit</b>
|
568 |
|
|
and <b>std::ios::eofbit</b> and
|
569 |
|
|
<b>std::ios::goodbit</b>.
|
570 |
|
|
</p>
|
571 |
|
|
</div>
|
572 |
|
|
<div class="section">
|
573 |
|
|
<div class="titlepage"><div><h2 class="title" style="clear: both">
|
574 |
|
|
<a name="sec-vector-at"></a>vector::at is missing (i.e. gcc 2.95.x)</h2></div></div>
|
575 |
|
|
<p>
|
576 |
|
|
One solution is to add an autoconf-test for this:
|
577 |
|
|
<pre class="programlisting">
|
578 |
|
|
AC_MSG_CHECKING(for container::at)
|
579 |
|
|
AC_TRY_COMPILE(
|
580 |
|
|
[
|
581 |
|
|
#include <vector>
|
582 |
|
|
#include <deque>
|
583 |
|
|
#include <string>
|
584 |
|
|
|
585 |
|
|
using namespace std;
|
586 |
|
|
],
|
587 |
|
|
[
|
588 |
|
|
deque<int> test_deque(3);
|
589 |
|
|
test_deque.at(2);
|
590 |
|
|
vector<int> test_vector(2);
|
591 |
|
|
test_vector.at(1);
|
592 |
|
|
string test_string("test_string");
|
593 |
|
|
test_string.at(3);
|
594 |
|
|
],
|
595 |
|
|
[AC_MSG_RESULT(yes)
|
596 |
|
|
AC_DEFINE(HAVE_CONTAINER_AT)],
|
597 |
|
|
[AC_MSG_RESULT(no)])
|
598 |
|
|
</pre>
|
599 |
|
|
If you are using other (non-GNU) compilers it might be a good idea
|
600 |
|
|
to check for <b>string::at</b> separately.
|
601 |
|
|
</p>
|
602 |
|
|
</div>
|
603 |
|
|
<div class="section">
|
604 |
|
|
<div class="titlepage"><div><h2 class="title" style="clear: both">
|
605 |
|
|
<a name="sec-eof"></a>Using std::char_traits<char>::eof()</h2></div></div>
|
606 |
|
|
<p>
|
607 |
|
|
<pre class="programlisting">
|
608 |
|
|
#ifdef HAVE_CHAR_TRAITS
|
609 |
|
|
#define CPP_EOF std::char_traits<char>::eof()
|
610 |
|
|
#else
|
611 |
|
|
#define CPP_EOF EOF
|
612 |
|
|
#endif
|
613 |
|
|
</pre>
|
614 |
|
|
</p>
|
615 |
|
|
</div>
|
616 |
|
|
<div class="section">
|
617 |
|
|
<div class="titlepage"><div><h2 class="title" style="clear: both">
|
618 |
|
|
<a name="sec-string-clear"></a>Using string::clear()/string::erase()</h2></div></div>
|
619 |
|
|
<p>
|
620 |
|
|
There are two functions for deleting the contents of a string:
|
621 |
|
|
<b>clear</b> and <b>erase</b> (the latter
|
622 |
|
|
returns the string).
|
623 |
|
|
<pre class="programlisting">
|
624 |
|
|
void
|
625 |
|
|
clear() { _M_mutate(0, this->size(), 0); }
|
626 |
|
|
</pre>
|
627 |
|
|
<pre class="programlisting">
|
628 |
|
|
basic_string&
|
629 |
|
|
erase(size_type __pos = 0, size_type __n = npos)
|
630 |
|
|
{
|
631 |
|
|
return this->replace(_M_check(__pos), _M_fold(__pos, __n),
|
632 |
|
|
_M_data(), _M_data());
|
633 |
|
|
}
|
634 |
|
|
</pre>
|
635 |
|
|
The implementation of <b>erase</b> seems to be more
|
636 |
|
|
complicated (from libstdc++-v3), but <b>clear</b> is not
|
637 |
|
|
implemented in gcc 2.95.x's libstdc++, so you should use
|
638 |
|
|
<b>erase</b> (which is probably faster than
|
639 |
|
|
<b>operator=(charT*)</b>).
|
640 |
|
|
</p>
|
641 |
|
|
</div>
|
642 |
|
|
<div class="section">
|
643 |
|
|
<div class="titlepage"><div><h2 class="title" style="clear: both">
|
644 |
|
|
<a name="sec-scan-form"></a>GNU Extensions ostream::form and istream::scan</h2></div></div>
|
645 |
|
|
<p>
|
646 |
|
|
These are not supported any more - use
|
647 |
|
|
<a href="#sec-stringstream" title="Using stringstreams">
|
648 |
|
|
stringstreams</a> instead.
|
649 |
|
|
</p>
|
650 |
|
|
</div>
|
651 |
|
|
<div class="section">
|
652 |
|
|
<div class="titlepage"><div><h2 class="title" style="clear: both">
|
653 |
|
|
<a name="sec-stringstream"></a>Using stringstreams</h2></div></div>
|
654 |
|
|
<p>
|
655 |
|
|
Libstdc++-v3 provides the new
|
656 |
|
|
<b>i/ostringstream</b>-classes, (<tt><sstream></tt>), but for compatibility
|
657 |
|
|
with older implementations you still have to use
|
658 |
|
|
<b>i/ostrstream</b> (<tt><strstream></tt>):
|
659 |
|
|
<pre class="programlisting">
|
660 |
|
|
#ifdef HAVE_SSTREAM
|
661 |
|
|
#include <sstream>
|
662 |
|
|
#else
|
663 |
|
|
#include <strstream>
|
664 |
|
|
#endif
|
665 |
|
|
</pre>
|
666 |
|
|
<div class="itemizedlist"><ul type="disc">
|
667 |
|
|
<li><p> <b>strstream</b> is considered to be
|
668 |
|
|
deprecated
|
669 |
|
|
</p></li>
|
670 |
|
|
<li><p> <b>strstream</b> is limited to
|
671 |
|
|
<b>char</b>
|
672 |
|
|
</p></li>
|
673 |
|
|
<li><p> with <b>ostringstream</b> you don't
|
674 |
|
|
have to take care of terminating the string or freeing its
|
675 |
|
|
memory
|
676 |
|
|
</p></li>
|
677 |
|
|
<li><p> <b>istringstream</b> can be re-filled
|
678 |
|
|
(clear(); str(input);)
|
679 |
|
|
</p></li>
|
680 |
|
|
</ul></div>
|
681 |
|
|
</p>
|
682 |
|
|
<p>
|
683 |
|
|
You can then use output-stringstreams like this:
|
684 |
|
|
<pre class="programlisting">
|
685 |
|
|
#ifdef HAVE_SSTREAM
|
686 |
|
|
std::ostringstream oss;
|
687 |
|
|
#else
|
688 |
|
|
std::ostrstream oss;
|
689 |
|
|
#endif
|
690 |
|
|
oss << "Name=" << m_name << ", number=" << m_number << std::endl;
|
691 |
|
|
...
|
692 |
|
|
#ifndef HAVE_SSTREAM
|
693 |
|
|
oss << std::ends; // terminate the char*-string
|
694 |
|
|
#endif
|
695 |
|
|
// str() returns char* for ostrstream and a string for ostringstream
|
696 |
|
|
// this also causes ostrstream to think that the buffer's memory
|
697 |
|
|
// is yours
|
698 |
|
|
m_label.set_text(oss.str());
|
699 |
|
|
#ifndef HAVE_SSTREAM
|
700 |
|
|
// let the ostrstream take care of freeing the memory
|
701 |
|
|
oss.freeze(false);
|
702 |
|
|
#endif
|
703 |
|
|
</pre>
|
704 |
|
|
</p>
|
705 |
|
|
<p>
|
706 |
|
|
Input-stringstreams can be used similarly:
|
707 |
|
|
<pre class="programlisting">
|
708 |
|
|
std::string input;
|
709 |
|
|
...
|
710 |
|
|
#ifdef HAVE_SSTREAM
|
711 |
|
|
std::istringstream iss(input);
|
712 |
|
|
#else
|
713 |
|
|
std::istrstream iss(input.c_str());
|
714 |
|
|
#endif
|
715 |
|
|
int i;
|
716 |
|
|
iss >> i;
|
717 |
|
|
</pre>
|
718 |
|
|
One (the only?) restriction is that an istrstream cannot be re-filled:
|
719 |
|
|
<pre class="programlisting">
|
720 |
|
|
std::istringstream iss(numerator);
|
721 |
|
|
iss >> m_num;
|
722 |
|
|
// this is not possible with istrstream
|
723 |
|
|
iss.clear();
|
724 |
|
|
iss.str(denominator);
|
725 |
|
|
iss >> m_den;
|
726 |
|
|
</pre>
|
727 |
|
|
If you don't care about speed, you can put these conversions in
|
728 |
|
|
a template-function:
|
729 |
|
|
<pre class="programlisting">
|
730 |
|
|
template <class X>
|
731 |
|
|
void fromString(const string& input, X& any)
|
732 |
|
|
{
|
733 |
|
|
#ifdef HAVE_SSTREAM
|
734 |
|
|
std::istringstream iss(input);
|
735 |
|
|
#else
|
736 |
|
|
std::istrstream iss(input.c_str());
|
737 |
|
|
#endif
|
738 |
|
|
X temp;
|
739 |
|
|
iss >> temp;
|
740 |
|
|
if (iss.fail())
|
741 |
|
|
throw runtime_error(..)
|
742 |
|
|
any = temp;
|
743 |
|
|
}
|
744 |
|
|
</pre>
|
745 |
|
|
Another example of using stringstreams is in <a href="../21_strings/howto.html" target="_top">this howto</a>.
|
746 |
|
|
</p>
|
747 |
|
|
<p>
|
748 |
|
|
I have read the Josuttis book on Standard C++, so some information
|
749 |
|
|
comes from there. Additionally, there is information in
|
750 |
|
|
"info iostream", which covers the old implementation that gcc 2.95.x
|
751 |
|
|
uses.
|
752 |
|
|
</p>
|
753 |
|
|
</div>
|
754 |
|
|
<div class="section">
|
755 |
|
|
<div class="titlepage"><div><h2 class="title" style="clear: both">
|
756 |
|
|
<a name="sec-about"></a>About...</h2></div></div>
|
757 |
|
|
<p>
|
758 |
|
|
Please send any experience, additions, corrections or questions to
|
759 |
|
|
<a href="mailto:fnatter@gmx.net" target="_top">fnatter@gmx.net</a> or for
|
760 |
|
|
discussion to the libstdc++-v3-mailing-list.
|
761 |
|
|
</p>
|
762 |
|
|
</div>
|
763 |
|
|
</div></body>
|
764 |
|
|
</html>
|