mirror of
git://gcc.gnu.org/git/gcc.git
synced 2024-12-24 06:09:06 +08:00
754ac8f7b2
2000-05-03 Phil Edwards <pme@sourceware.cygnus.com> Felix Natter <fnatter@gmx.net> * docs/footer.html: Update to see if it takes effect. * docs/thanks.html: More people. * docs/17_intro/headers_cc.txt: Copy from testsuite, since that can't be seen from the web pages. Rename for browser-friendliness... * docs/17_intro/howto.html: ...and update here. * docs/17_intro/porting-howto.html: Changes from Felix. * docs/gccrebuild.html: Mention v3->egcs move. * docs/faq/index.html: Ditto. Also misc tweaks and URL updates. * docs/faq/index.txt: Regenerate. Co-Authored-By: Felix Natter <fnatter@gmx.net> From-SVN: r33631
306 lines
11 KiB
HTML
306 lines
11 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
|
|
|
<html>
|
|
|
|
<head>
|
|
<title>Libstdc++-porting-howto</title>
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<h1>Porting to libstdc++-v3</h1>
|
|
|
|
<center>
|
|
<li><a href = "#std">Namespaces std</a>
|
|
<li><a href = "#nocreate">File-flags: <tt>ios::nocreate</tt> and
|
|
<tt>ios::noreplace</tt></a>
|
|
<li><a href = "#headers">The new headers</a>
|
|
<li><a href = "#iterators">Iterator-changes</a>
|
|
<li><a href = "#macros">Libc-macros</a>
|
|
<li><a href = "#about">Comments, suggestions, corrections, questions...</a>
|
|
</center>
|
|
|
|
<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>
|
|
|
|
<a name = "std">
|
|
<h2>Namespace std::</h2>
|
|
</a>
|
|
<p>
|
|
The latest C++-standard (ISO-14882) requires that the standard C++-library
|
|
is defined in namespace std::. Thus, to use classes from the standard c++
|
|
library, you can do one of three things:
|
|
<ul>
|
|
<li>wrap your code in <tt>namespace std { ... }</tt> => This is not an
|
|
option because only symbols from the standard c++-library are defined in
|
|
namespace std::.
|
|
|
|
<li>put a kind of <dfn>using-declaration</dfn> in your source (either
|
|
<tt>using namespace std;</tt> or i.e. <tt>using std::string;</tt>)
|
|
=> works well for source-files, but cannot be used in header-files
|
|
|
|
<li>use a <dfn>fully qualified name</dfn> for each libstdc++-symbol
|
|
(i.e. <tt>std::string</tt>, <tt>std::cout</tt>) => can always be used
|
|
</ul>
|
|
</p>
|
|
<p>
|
|
Because there are many compilers which still use an implementation that
|
|
does not have the standard C++-library in namespace <tt>std::</tt>, 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 <tt>std::</tt> use
|
|
<tt>-fno-honor-std</tt> (ignore <tt>std::</tt>, <tt>:: = std::</tt>) by
|
|
default. That is, the responsibility for enabling or disabling
|
|
<tt>std::</tt> 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>
|
|
<a name = "gtkmm">
|
|
<h3>Using <dfn>namespace composition</dfn> if the project uses a separate
|
|
namespace</h3>
|
|
</a>
|
|
|
|
<p>
|
|
<a href = "http://gtkmm.sourcforge.net">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 <dfn>namespace
|
|
composition</dfn>. This is what happens if you put a
|
|
<dfn>using</dfn>-declaration into a namespace-definition: the imported
|
|
symbol(s) gets imported into the currently active namespace(s). For example:
|
|
<pre>
|
|
namespace Gtk {
|
|
using std::string;
|
|
class Window { ... }
|
|
}
|
|
</pre>
|
|
In this example, <tt>std::string</tt> gets imported into namespace Gtk::.
|
|
The result is that you don't have to use <tt>std::string</tt> in this
|
|
header, but still <tt>std::string</tt> does not get imported into
|
|
user-space (the global namespace ::) unless the user does <tt>using
|
|
namespace Gtk;</tt> (which is not recommended practice for Gtk--, so it is
|
|
not a problem). Additionally, the <tt>using</tt>-declarations are wrapped
|
|
in macros that are set based on autoconf-tests to either "" or
|
|
i.e. <tt>using std::string;</tt> (depending on whether the system has
|
|
libstdc++ in <tt>std::</tt> or not).
|
|
(ideas from llewelly@dbritsch.dsl.xmission.com,
|
|
Karl Nelson <kenelson@ece.ucdavis.edu>)
|
|
</p>
|
|
|
|
<h3>Defining an empty namespace std</h3>
|
|
<p>
|
|
By defining an (empty) namespace <tt>std::</tt> before using it, you can
|
|
avoid getting errors on systems where no part of the library is in
|
|
namespace std:
|
|
<pre>
|
|
namespace std { }
|
|
using namespace std;
|
|
</pre>
|
|
</p>
|
|
<h3>Avoid to use fully qualified names (i.e. std::string)</h3>
|
|
<p>
|
|
If some compilers complain about <tt>using std::string;</tt>, and if the
|
|
"hack" for gtk-- mentioned above does not work, then it might be a good idea
|
|
to define a macro <tt>NS_STD</tt>, which is defined to either "" or "std"
|
|
based on an autoconf-test. Then you should be able to use
|
|
<tt>NS_STD::string</tt>, which will evaluate to <tt>::string</tt> ("string
|
|
in the global namespace") on systems that do not put string in std::.
|
|
(This is untested)
|
|
</p>
|
|
|
|
<h3>How some open-source-projects deal with this</h3>
|
|
<p>
|
|
|
|
<table>
|
|
<tr><td><a href = "http://www.clanlib.org">clanlib</a></td> <td>usual</td>
|
|
</tr>
|
|
<tr><td><a href = "http://pingus.seul.org">pingus</a></td> <td>usual</td>
|
|
</tr>
|
|
<tr><td><a href = "http://www.mozilla.org">mozilla</a></td> <td>usual</td>
|
|
</tr>
|
|
<tr><td><a href = "http://www.mnemonic.org">mnemonic</a></td> <td>none</td>
|
|
</tr>
|
|
<tr><td><a href = "http://libsigc.sourceforge.net">libsigc++</a></td>
|
|
<td>conservative-impl</td>
|
|
</tr>
|
|
</table>
|
|
|
|
<table>
|
|
<caption>Notations for categories</caption>
|
|
<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>
|
|
</table>
|
|
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 the <a href = "#gtkmm">Gtk-- "hack"</a>).
|
|
</p>
|
|
<a name = "nocreate">
|
|
<h2>there is no ios::nocreate/ios::noreplace in ISO 14882</h2>
|
|
</a>
|
|
<p>
|
|
I have seen <tt>ios::nocreate</tt> being used for input-streams, most
|
|
probably because the authors 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
|
|
<tt>std::ios::trunc</tt> ? 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
|
|
<tt>app</tt>, <tt>ate</tt> and <tt>trunc</tt> (except for <tt>app</tt> ?).
|
|
</p>
|
|
<a name = "attach">
|
|
<h2><tt>stream::attach(int fd)</tt> is not in the standard any more</h2>
|
|
</a>
|
|
<p>
|
|
With libstdc++-v3, you can use
|
|
<pre>
|
|
basic_filebuf(int __fd, const char*__name, ios_base::openmode __mode)
|
|
</pre>
|
|
For a portable solution (if there is one), you need to implement
|
|
a subclass of <tt>streambuf</tt> which opens a file given a descriptor,
|
|
and then pass an instance of this to the stream-constructor (from the
|
|
Josuttis-book).
|
|
</p>
|
|
<a name = "headers">
|
|
<h2>The new headers</h2>
|
|
</a>
|
|
<p>
|
|
The new headers can be seen in this
|
|
<a href = "../../testsuite/17_intro/headers.cc">source file</a>.
|
|
</p>
|
|
<p>
|
|
I think it is a problem for libstdc++-v3 to add links or wrappers for the
|
|
old headers, because the implementation has changed, and the
|
|
header-name-changes indicate this. It might be preferable to use the new
|
|
headers and tell users of old compilers that they should create links
|
|
(which is what they will have to do sometime anyway).
|
|
</p>
|
|
|
|
<a name = "cheaders">
|
|
<h3>New headers replacing C-headers</h3>
|
|
</a>
|
|
<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, ommiting the extension (.h). For example,
|
|
instead of using <tt><math.h></tt>, you should use
|
|
<tt><cmath></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 <tt>std::</tt>
|
|
(libstdc++-v3, version 2.90.8 currently puts them in <tt>std::</tt> only)
|
|
On the other hand, if you include only the new header
|
|
(i.e. <tt><cmath></tt>), the symbols will only be defined in
|
|
namespace <tt>std::</tt> (and macros will be converted to
|
|
inline-functions).
|
|
</p>
|
|
<p>
|
|
For more information on this, and for information on how the GNU C++
|
|
implementation reuses ("shadows") the C library-functions, have
|
|
a look at <a href = "http://www.cantrip.org/cheaders.html">www.cantrip.org</a>.
|
|
</p>
|
|
|
|
<h3><tt><fstream></tt> does not define <tt>std::cout</tt>,
|
|
<tt>std::cin</tt> etc.</h3>
|
|
<p>
|
|
In previous versions of the standard, <tt><fstream.h></tt>,
|
|
<tt><ostream.h></tt> and <tt><istream.h></tt> used to define
|
|
<tt>cout</tt>, <tt>cin</tt> and so on. Because of the templatized iostreams
|
|
in libstdc++-v3, you need to include <tt><iostream></tt> explicitly
|
|
to define these.
|
|
</p>
|
|
|
|
<a name = "iterators">
|
|
<h2>Iterators</h2>
|
|
</a>
|
|
<p>
|
|
The following are not proper uses of iterators, but may be working fixes
|
|
for existing uses of iterators.
|
|
<ul>
|
|
<li>you cannot do <tt>ostream::operator<<(iterator)</tt> to print the
|
|
address of the iterator => use <tt><< &*iterator</tt> instead ?
|
|
<li>you cannot clear an iterator's reference (<tt>iterator = 0</tt>)
|
|
=> use <tt>iterator = iterator_type();</tt> ?
|
|
<li><tt>if (iterator)</tt> won't work any more
|
|
=> use <tt>if (iterator != iterator_type())</tt> ?
|
|
</ul>
|
|
</p>
|
|
|
|
<a name = "macros">
|
|
<h2>Libc-macros (i.e. <tt>isspace</tt> from <tt><cctype></tt>)</h2>
|
|
</a>
|
|
<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 = "#cheaders">section on C-headers</a>.
|
|
</p>
|
|
<p>
|
|
Older implementations of libstdc++ (g++-2 for egcs 1.x and g++-3 for
|
|
gcc 2.95.2), however, keep these functions as macros, and so it is not
|
|
back-portable to use fully qualified names. For example:
|
|
<pre>
|
|
#include <cctype>
|
|
int main() { std::isspace('X'); }
|
|
</pre>
|
|
will result in something like this (unless using g++-v3):
|
|
<pre>
|
|
std:: (__ctype_b[(int) ( ( 'X' ) )] & (unsigned short int) _ISspace ) ;
|
|
</pre>
|
|
Another problem arises if you put a <tt>using namespace std;</tt>
|
|
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 <tt>std::</tt>
|
|
(<tt><cctype></tt>).
|
|
</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.2)
|
|
enable a macro which tells <ctype.h> to define functions instead of
|
|
macros:
|
|
<pre>
|
|
// This keeps isanum, et al from being propagated as macros.
|
|
#if __linux__
|
|
#define __NO_CTYPE 1
|
|
#endif
|
|
|
|
[ now include <ctype.h> ]
|
|
</pre>
|
|
</p>
|
|
|
|
<a name = "about">
|
|
<h2>About...</h2>
|
|
</a>
|
|
<p>
|
|
Please send any experience, additions, corrections or questions to <a href
|
|
= "mailto:fnatter@gmx.net">fnatter@gmx.net</a> or for discussion to the
|
|
libstdc++-v3-mailing-list.
|
|
</p>
|
|
|
|
</body>
|
|
|
|
</html>
|