From 320f95489d1a822d0b67fa63aa5691d70cd3ae0d Mon Sep 17 00:00:00 2001
From: Felix Natter
-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".
-
-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:
- Porting to libstdc++-v3
-
- Namespace std::
-
-
-
-
-Because there are many compilers which still use an implementation that -does not have the standard C++-library in namespace std::, some -care is required to support these as well. -
--Namespace back-portability-issues are generally not a problem with g++, -because versions of g++ that do not have libstdc++ in std:: use --fno-honor-std (ignore std::, :: = std::) by -default. That is, the responsibility for enabling or disabling -std:: is on the user; the maintainer does not have to care about it. -This probably applies to some other compilers as well. -
--The following sections list some possible solutions to support compilers -that cannot ignore std::. -
- --Gtk-- defines most of its -classes in namespace Gtk::. Thus, it was possible to adapt Gtk-- to -namespace std:: by using a C++-feature called namespace -composition. This is what happens if you put a -using-declaration into a namespace-definition: the imported -symbol(s) gets imported into the currently active namespace(s). For example: -
-namespace Gtk { - using std::string; - class Window { ... } -} --In this example, std::string gets imported into namespace Gtk::. -The result is that you don't have to use std::string in this -header, but still std::string does not get imported into -user-space (the global namespace ::) unless the user does using -namespace Gtk; (which is not recommended practice for Gtk--, so it is -not a problem). Additionally, the using-declarations are wrapped -in macros that are set based on autoconf-tests to either "" or -i.e. using std::string; (depending on whether the system has -libstdc++ in std:: or not). -(ideas from llewelly@dbritsch.dsl.xmission.com, -Karl Nelson
-By defining an (empty) namespace std:: before using it, you can -avoid getting errors on systems where no part of the library is in -namespace std: -
-namespace std { } -using namespace std; -- -
-If some compilers complain about using std::string;, and if the -"hack" for gtk-- mentioned above does not work, then it might be a good idea -to define a macro NS_STD, which is defined to either "" or "std" -based on an autoconf-test. Then you should be able to use -NS_STD::string, which will evaluate to ::string ("string -in the global namespace") on systems that do not put string in std::. -(This is untested) -
- -- -
clanlib | usual | -
pingus | usual | -
mozilla | usual | -
mnemonic | none | -
libsigc++ | -conservative-impl | -
usual | mostly fully qualified names and some - using-declarations (but not in headers) | -
none | no namespace std at all | -
conservative-impl | wrap all namespace-handling in macros to - support compilers without namespace-support (no libstdc++ used in - headers) | -
-I have seen ios::nocreate 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. -
--For output streams, "nocreate" is probably the default, unless you specify -std::ios::trunc ? 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 -app, ate and trunc (except for app ?). -
- --With libstdc++-v3, you can use -
-basic_filebuf(int __fd, const char*__name, ios_base::openmode __mode) --For a portable solution (if there is one), you need to implement -a subclass of streambuf which opens a file given a descriptor, -and then pass an instance of this to the stream-constructor (from the -Josuttis-book). - - -
-The new headers can be seen in this -source file. -
--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). -
- - --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 <math.h>, you should use -<cmath>. The standard specifies that if you include the -C-style header (<math.h> in this case), the symbols will be -available both in the global namespace and in namespace std:: -(libstdc++-v3, version 2.90.8 currently puts them in std:: only) -On the other hand, if you include only the new header -(i.e. <cmath>), the symbols will only be defined in -namespace std:: (and macros will be converted to -inline-functions). -
+ +-For more information on this, and for information on how the GNU C++ -implementation reuses ("shadows") the C library-functions, have -a look at www.cantrip.org. -
- -what kind of a date ? I don't drink !
+Revision History | +||
---|---|---|
Revision 0.5 | Thu Jun 1 13:06:50 2000 | fnatter | +
First docbook-version. | +||
Revision 0.8 | Sun Jul 30 20:28:40 2000 | fnatter | +
First released version using docbook-xml + + second upload to libstdc++-page. + | +
+ 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. +
+-In previous versions of the standard, <fstream.h>, -<ostream.h> and <istream.h> used to define -cout, cin and so on. Because of the templatized iostreams -in libstdc++-v3, you need to include <iostream> explicitly -to define these. -
+ Table of Contents + ++ 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". +
++ 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: +
wrap your code in namespace std { + ... } => This is not an option because only symbols + from the standard c++-library are defined in namespace std::. +
+put a kind of + using-declaration in your source (either + using namespace std; or i.e. using + std::string;) => works well for source-files, but + cannot be used in header-files. +
+use a fully qualified name for + each libstdc++-symbol (i.e. std::string, + std::cout) => can always be used +
++ Because there are many compilers which still use an implementation + that does not have the standard C++-library in namespace + std::, some care is required to support these as + well. +
++ Namespace back-portability-issues are generally not a problem with + g++, because versions of g++ that do not have libstdc++ in + std:: use -fno-honor-std + (ignore std::, :: = std::) by + default. That is, the responsibility for enabling or disabling + std:: is on the user; the maintainer does not have + to care about it. This probably applies to some other compilers as + well. +
++ The following sections list some possible solutions to support compilers + that cannot ignore std::. +
++ Gtk-- defines + most of its classes in namespace Gtk::. Thus, it was possible to + adapt Gtk-- to namespace std:: by using a C++-feature called + namespace composition. This is what happens if + you put a using-declaration into a + namespace-definition: the imported symbol(s) gets imported into the + currently active namespace(s). For example: +
+ namespace Gtk { + using std::string; + class Window { ... } + } ++ In this example, std::string gets imported into + namespace Gtk::. The result is that you don't have to use + std::string in this header, but still + std::string does not get imported into + user-space (the global namespace ::) unless the user does + using namespace Gtk; (which is not recommended + practice for Gtk--, so it is not a problem). Additionally, the + using-declarations are wrapped in macros that + are set based on autoconf-tests to either "" or i.e. using + std::string; (depending on whether the system has + libstdc++ in std:: or not). (ideas from + <llewelly@dbritsch.dsl.xmission.com>, Karl Nelson + <kenelson@ece.ucdavis.edu>) + +
+ By defining an (empty) namespace std:: before + using it, you avoid getting errors on systems where no part of the + library is in namespace std: +
+ namespace std { } + using namespace std; ++ +
+ If some compilers complain about using + std::string;, and if the "hack" for gtk-- mentioned above + does not work, then it might be a good idea to define a macro + NS_STD, which is defined to either "" or "std" + based on an autoconf-test. Then you should be able to use + NS_STD::string, which will evaluate to + ::string ("string in the global namespace") on + systems that do not put string in std::. (This is untested) +
++ This information was gathered around May 2000. It may not be correct + by the time you read this. +
++ Table 1. Namespace std:: in Open-Source programs +
+clanlib | usual | +
pingus | usual | +
mozilla | usual | +
mnemonic | none | +
+ libsigc++ | conservative-impl | +
+ Table 2. Notations for categories +
+usual | mostly fully qualified names and some + using-declarations (but not in headers) | +
none | no namespace std at all | +
conservative-impl | wrap all + namespace-handling in macros to support compilers without + namespace-support (no libstdc++ used in headers) | +
+ 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 section on the Gtk-- hack + ). +
++ I have seen ios::nocreate 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. +
++ For output streams, "nocreate" is probably the default, unless you + specify std::ios::trunc ? 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 app, + ate and trunc (except for + app ?). +
++ When using libstdc++-v3, you can use +
+ For a portable solution (if there is one), you need to implement a + subclass of streambuf which opens a file given a + descriptor, and then pass an instance of this to the + stream-constructor (from the Josuttis-book). + ++ All new headers can be seen in this source-code. +
++ 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). +
++ 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 <math.h>, you should use <cmath>. The standard + specifies that if you include the C-style header (<math.h> in this case), the symbols + will be available both in the global namespace and in namespace + std:: (libstdc++-v3, version 2.90.8 currently + puts them in std:: only) On the other hand, if + you include only the new header (i.e. <pcmath>), the symbols will only be + defined in namespace std:: (and macros will be + converted to inline-functions). +
++ For more information on this, and for information on how the GNU + C++ implementation reuses ("shadows") the C library-functions, have + a look at + www.cantrip.org. +
++ In previous versions of the standard, <fstream.h>, <ostream.h> and <istream.h> used to define + cout, cin and so on. Because + of the templatized iostreams in libstdc++-v3, you need to include + <iostream> + explicitly to define these. +
++ The following are not proper uses of iterators, but may be working + fixes for existing uses of iterators. +
you cannot do + ostream::operator<<(iterator) to + print the address of the iterator => use + operator<< &*iterator instead ? +
+you cannot clear an iterator's reference + (iterator = 0) => use + iterator = iterator_type(); ? +
++ if (iterator) won't work any + more => use if (iterator != iterator_type()) + ?
++ Glibc 2.0.x and 2.1.x define the <ctype.h> -functionality as + macros (isspace, isalpha etc.). Libstdc++-v3 "shadows" these macros + as described in the section on C-headers. +
++ 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: +
+ #include <cctype> + int main() { std::isspace('X'); } ++ will result in something like this (unless using g++-v3): +
+ std:: (__ctype_b[(int) ( ( 'X' ) )] & (unsigned short int) + _ISspace ) ; ++ +
+ 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 ?). +
++ 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) define a + macro which tells <ctype.h> to define functions + instead of macros: +
+ // This keeps isalnum, et al from being propagated as macros. + #if __linux__ + #define __NO_CTYPE 1 + #endif - -Iterators
- --The following are not proper uses of iterators, but may be working fixes -for existing uses of iterators. -
-Glibc 2.0.x and 2.1.x define the <ctype.h>-functionality -as macros (isspace, isalpha etc.). Libstdc++-v3 "shadows" these macros -as described in the section on C-headers. -
--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: -
-#include <cctype> -int main() { std::isspace('X'); } --will result in something like this (unless using g++-v3): -
-std:: (__ctype_b[(int) ( ( 'X' ) )] & (unsigned short int) _ISspace ) ; --Another problem arises if you put a using namespace std; -declaration at the top, and include <ctype.h>. This will -result in ambiguities between the definitions in the global namespace -(<ctype.h>) and the definitions in namespace std:: -(<cctype>). - -
-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 ?). -
--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: -
-// This keeps isanum, et al from being propagated as macros. -#if __linux__ -#define __NO_CTYPE 1 -#endif - -[ now include <ctype.h> ] -- - - -
-Please send any experience, additions, corrections or questions to fnatter@gmx.net or for discussion to the -libstdc++-v3-mailing-list. -
- + [ now include <ctype.h> ] + + ++ Another problem arises if you put a using namespace + std; declaration at the top, and include <ctype.h>. This will result in + ambiguities between the definitions in the global namespace + (<ctype.h>) and the + definitions in namespace std:: + (<cctype>). +
++ The solution to this problem was posted to the libstdc++-v3 + mailing-list: + Benjamin Kosnik <bkoz@redhat.com> writes: + " + --enable-cshadow-headers is currently broken. As a result, shadow + headers are not being searched.... + " +
++ Please send any experience, additions, corrections or questions to + fnatter@gmx.net or for + discussion to the libstdc++-v3-mailing-list. +
+