1 <section xmlns="http://docbook.org/ns/docbook" version="5.0"
2 xml:id="manual.appendix.porting.backwards" xreflabel="backwards">
3 <?dbhtml filename="backwards.html"?>
5 <info><title>Backwards Compatibility</title>
7 <keyword>ISO C++</keyword>
8 <keyword>backwards</keyword>
14 <section xml:id="backwards.first"><info><title>First</title></info>
17 <para>The first generation GNU C++ library was called libg++. It was a
18 separate GNU project, although reliably paired with GCC. Rumors imply
19 that it had a working relationship with at least two kinds of
23 <para>Some background: libg++ was designed and created when there was no
24 ISO standard to provide guidance. Classes like linked lists are now
25 provided for by <classname>std::list<T></classname> and do not need to be
26 created by <function>genclass</function>. (For that matter, templates exist
27 now and are well-supported, whereas genclass (mostly) predates them.)
30 <para>There are other classes in libg++ that are not specified in the
31 ISO Standard (e.g., statistical analysis). While there are a lot of
32 really useful things that are used by a lot of people, the Standards
33 Committee couldn't include everything, and so a lot of those
34 <quote>obvious</quote> classes didn't get included.
37 <para>That project is no longer maintained or supported, and the sources
38 archived. For the desperate, the
39 <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://ftp.gnu.org/old-gnu/libg++/">ftp.gnu.org</link>
40 server still has the libg++ source.
44 <section xml:id="backwards.second"><info><title>Second</title></info>
48 The second generation GNU C++ library was called libstdc++, or
49 libstdc++-v2. It spans the time between libg++ and pre-ISO C++
50 standardization and is usually associated with the following GCC
51 releases: egcs 1.x, gcc 2.95, and gcc 2.96.
55 The STL portions of that library are based on SGI/HP STL release 3.11.
59 That project is no longer maintained or supported, and the sources
60 archived. The code was replaced and rewritten for libstdc++-v3.
65 <section xml:id="backwards.third"><info><title>Third</title></info>
68 <para> The third generation GNU C++ library is called libstdc++, or
72 <para>The subset commonly known as the Standard Template Library
73 (clauses 23 through 25 in C++98, mostly) is adapted from the final release
74 of the SGI STL (version 3.3), with extensive changes.
77 <para>A more formal description of the V3 goals can be found in the
78 official <link linkend="contrib.design_notes">design document</link>.
81 <para>Portability notes and known implementation limitations are as follows.</para>
83 <section xml:id="backwards.third.headers"><info><title>Pre-ISO headers removed</title></info>
86 <para> The pre-ISO C++ headers
87 (<filename class="headerfile"><iostream.h></filename>,
88 <filename class="headerfile"><defalloc.h></filename> etc.) are
92 <para>For those of you new to ISO C++ (welcome, time travelers!), the
93 ancient pre-ISO headers have new names.
94 The C++ FAQ has a good explanation in <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://isocpp.org/wiki/faq/coding-standards#std-headers">What's
95 the difference between <xxx> and <xxx.h> headers?</link>.
98 <para>Porting between pre-ISO headers and ISO headers is simple: headers
99 like <filename class="headerfile"><vector.h></filename> can be replaced with <filename class="headerfile"><vector></filename> and a using
100 directive <code>using namespace std;</code> can be put at the global
101 scope. This should be enough to get this code compiling, assuming the
102 other usage is correct.
106 <section xml:id="backwards.third.hash"><info><title>Extension headers hash_map, hash_set moved to ext or backwards</title></info>
109 <para>At this time most of the features of the SGI STL extension have been
110 replaced by standardized libraries.
111 In particular, the <classname>unordered_map</classname> and
112 <classname>unordered_set</classname> containers of TR1 and C++ 2011
113 are suitable replacements for the non-standard
114 <classname>hash_map</classname> and <classname>hash_set</classname>
115 containers in the SGI STL.
117 <para> Header files <filename class="headerfile"><hash_map></filename> and <filename class="headerfile"><hash_set></filename> moved
118 to <filename class="headerfile"><ext/hash_map></filename> and <filename class="headerfile"><ext/hash_set></filename>,
119 respectively. At the same time, all types in these files are enclosed
120 in <code>namespace __gnu_cxx</code>. Later versions deprecate
121 these files, and suggest using TR1's <filename class="headerfile"><unordered_map></filename>
122 and <filename class="headerfile"><unordered_set></filename> instead.
125 <para>The extensions are no longer in the global or <code>std</code>
126 namespaces, instead they are declared in the <code>__gnu_cxx</code>
127 namespace. For maximum portability, consider defining a namespace
128 alias to use to talk about extensions, e.g.:
133 #include <hash_map.h>
134 namespace extension { using ::hash_map; }; // inherit globals
136 #include <backward/hash_map>
137 #if __GNUC__ == 3 && __GNUC_MINOR__ == 0
138 namespace extension = std; // GCC 3.0
140 namespace extension = ::__gnu_cxx; // GCC 3.1 and later
143 #else // ... there are other compilers, right?
144 namespace extension = std;
147 extension::hash_map<int,int> my_map;
149 <para>This is a bit cleaner than defining typedefs for all the
150 instantiations you might need.
154 <para>The following autoconf tests check for working HP/SGI hash containers.
158 # AC_HEADER_EXT_HASH_MAP
159 AC_DEFUN([AC_HEADER_EXT_HASH_MAP], [
160 AC_CACHE_CHECK(for ext/hash_map,
161 ac_cv_cxx_ext_hash_map,
164 ac_save_CXXFLAGS="$CXXFLAGS"
165 CXXFLAGS="$CXXFLAGS -Werror"
166 AC_TRY_COMPILE([#include <ext/hash_map>], [using __gnu_cxx::hash_map;],
167 ac_cv_cxx_ext_hash_map=yes, ac_cv_cxx_ext_hash_map=no)
168 CXXFLAGS="$ac_save_CXXFLAGS"
171 if test "$ac_cv_cxx_ext_hash_map" = yes; then
172 AC_DEFINE(HAVE_EXT_HASH_MAP,,[Define if ext/hash_map is present. ])
178 # AC_HEADER_EXT_HASH_SET
179 AC_DEFUN([AC_HEADER_EXT_HASH_SET], [
180 AC_CACHE_CHECK(for ext/hash_set,
181 ac_cv_cxx_ext_hash_set,
184 ac_save_CXXFLAGS="$CXXFLAGS"
185 CXXFLAGS="$CXXFLAGS -Werror"
186 AC_TRY_COMPILE([#include <ext/hash_set>], [using __gnu_cxx::hash_set;],
187 ac_cv_cxx_ext_hash_set=yes, ac_cv_cxx_ext_hash_set=no)
188 CXXFLAGS="$ac_save_CXXFLAGS"
191 if test "$ac_cv_cxx_ext_hash_set" = yes; then
192 AC_DEFINE(HAVE_EXT_HASH_SET,,[Define if ext/hash_set is present. ])
198 <section xml:id="backwards.third.nocreate_noreplace"><info><title>No <code>ios::nocreate/ios::noreplace</code>.
202 <para>Historically these flags were used with iostreams to control whether
203 new files are created or not when opening a file stream, similar to the
204 <code>O_CREAT</code> and <code>O_EXCL</code> flags for the
205 <function>open(2)</function> system call. Because iostream modes correspond
206 to <function>fopen(3)</function> modes these flags are not supported.
207 For input streams a new file will not be created anyway, so
208 <code>ios::nocreate</code> is not needed.
209 For output streams, a new file will be created if it does not exist, which is
210 consistent with the behaviour of <function>fopen</function>.
213 <para>When one of these flags is needed a possible alternative is to attempt
214 to open the file using <type>std::ifstream</type> first to determine whether
215 the file already exists or not. This may not be reliable however, because
216 whether the file exists or not could change between opening the
217 <type>std::istream</type> and re-opening with an output stream. If you need
218 to check for existence and open a file as a single operation then you will
219 need to use OS-specific facilities outside the C++ standard library, such
220 as <function>open(2)</function>.
224 <section xml:id="backwards.third.streamattach"><info><title>
225 No <code>stream::attach(int fd)</code>
230 Phil Edwards writes: It was considered and rejected for the ISO
231 standard. Not all environments use file descriptors. Of those
232 that do, not all of them use integers to represent them.
236 For a portable solution (among systems which use
237 file descriptors), you need to implement a subclass of
238 <code>std::streambuf</code> (or
239 <code>std::basic_streambuf<..></code>) which opens a file
240 given a descriptor, and then pass an instance of this to the
245 An extension is available that implements this.
246 <filename class="headerfile"><ext/stdio_filebuf.h></filename>
247 contains a derived class called
248 <classname>__gnu_cxx::stdio_filebuf</classname>.
249 This class can be constructed from a C <code>FILE*</code> or a file
250 descriptor, and provides the <code>fd()</code> function.
254 For another example of this, refer to
255 <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.josuttis.com/cppcode/fdstream.html">fdstream example</link>
260 <section xml:id="backwards.third.support_cxx98"><info><title>
261 Support for C++98 dialect.
265 <para>Check for complete library coverage of the C++1998/2003 standard.
269 # AC_HEADER_STDCXX_98
270 AC_DEFUN([AC_HEADER_STDCXX_98], [
271 AC_CACHE_CHECK(for ISO C++ 98 include files,
276 #include <cassert>
277 #include <cctype>
278 #include <cerrno>
279 #include <cfloat>
280 #include <ciso646>
281 #include <climits>
282 #include <clocale>
283 #include <cmath>
284 #include <csetjmp>
285 #include <csignal>
286 #include <cstdarg>
287 #include <cstddef>
288 #include <cstdio>
289 #include <cstdlib>
290 #include <cstring>
291 #include <ctime>
293 #include <algorithm>
294 #include <bitset>
295 #include <complex>
296 #include <deque>
297 #include <exception>
298 #include <fstream>
299 #include <functional>
300 #include <iomanip>
302 #include <iosfwd>
303 #include <iostream>
304 #include <istream>
305 #include <iterator>
306 #include <limits>
307 #include <list>
308 #include <locale>
310 #include <memory>
312 #include <numeric>
313 #include <ostream>
314 #include <queue>
316 #include <sstream>
317 #include <stack>
318 #include <stdexcept>
319 #include <streambuf>
320 #include <string>
321 #include <typeinfo>
322 #include <utility>
323 #include <valarray>
324 #include <vector>
326 ac_cv_cxx_stdcxx_98=yes, ac_cv_cxx_stdcxx_98=no)
329 if test "$ac_cv_cxx_stdcxx_98" = yes; then
330 AC_DEFINE(STDCXX_98_HEADERS,,[Define if ISO C++ 1998 header files are present. ])
336 <section xml:id="backwards.third.support_tr1"><info><title>
337 Support for C++TR1 dialect.
341 <para>Check for library coverage of the TR1 standard.
345 # AC_HEADER_STDCXX_TR1
346 AC_DEFUN([AC_HEADER_STDCXX_TR1], [
347 AC_CACHE_CHECK(for ISO C++ TR1 include files,
348 ac_cv_cxx_stdcxx_tr1,
352 #include <tr1/array>
353 #include <tr1/ccomplex>
354 #include <tr1/cctype>
355 #include <tr1/cfenv>
356 #include <tr1/cfloat>
357 #include <tr1/cinttypes>
358 #include <tr1/climits>
359 #include <tr1/cmath>
360 #include <tr1/complex>
361 #include <tr1/cstdarg>
362 #include <tr1/cstdbool>
363 #include <tr1/cstdint>
364 #include <tr1/cstdio>
365 #include <tr1/cstdlib>
366 #include <tr1/ctgmath>
367 #include <tr1/ctime>
368 #include <tr1/cwchar>
369 #include <tr1/cwctype>
370 #include <tr1/functional>
371 #include <tr1/memory>
372 #include <tr1/random>
373 #include <tr1/regex>
374 #include <tr1/tuple>
375 #include <tr1/type_traits>
376 #include <tr1/unordered_set>
377 #include <tr1/unordered_map>
378 #include <tr1/utility>
380 ac_cv_cxx_stdcxx_tr1=yes, ac_cv_cxx_stdcxx_tr1=no)
383 if test "$ac_cv_cxx_stdcxx_tr1" = yes; then
384 AC_DEFINE(STDCXX_TR1_HEADERS,,[Define if ISO C++ TR1 header files are present. ])
389 <para>An alternative is to check just for specific TR1 includes, such as <unordered_map> and <unordered_set>.
393 # AC_HEADER_TR1_UNORDERED_MAP
394 AC_DEFUN([AC_HEADER_TR1_UNORDERED_MAP], [
395 AC_CACHE_CHECK(for tr1/unordered_map,
396 ac_cv_cxx_tr1_unordered_map,
399 AC_TRY_COMPILE([#include <tr1/unordered_map>], [using std::tr1::unordered_map;],
400 ac_cv_cxx_tr1_unordered_map=yes, ac_cv_cxx_tr1_unordered_map=no)
403 if test "$ac_cv_cxx_tr1_unordered_map" = yes; then
404 AC_DEFINE(HAVE_TR1_UNORDERED_MAP,,[Define if tr1/unordered_map is present. ])
410 # AC_HEADER_TR1_UNORDERED_SET
411 AC_DEFUN([AC_HEADER_TR1_UNORDERED_SET], [
412 AC_CACHE_CHECK(for tr1/unordered_set,
413 ac_cv_cxx_tr1_unordered_set,
416 AC_TRY_COMPILE([#include <tr1/unordered_set>], [using std::tr1::unordered_set;],
417 ac_cv_cxx_tr1_unordered_set=yes, ac_cv_cxx_tr1_unordered_set=no)
420 if test "$ac_cv_cxx_tr1_unordered_set" = yes; then
421 AC_DEFINE(HAVE_TR1_UNORDERED_SET,,[Define if tr1/unordered_set is present. ])
428 <section xml:id="backwards.third.support_cxx11"><info><title>
429 Support for C++11 dialect.
433 <para>Check for baseline language coverage in the compiler for the C++11 standard.
437 # AC_COMPILE_STDCXX_11
438 AC_DEFUN([AC_COMPILE_STDCXX_11], [
439 AC_CACHE_CHECK(if g++ supports C++11 features without additional flags,
440 ac_cv_cxx_compile_cxx11_native,
444 template <typename T>
447 static constexpr T value{ __cplusplus };
450 typedef check<check<bool>> right_angle_brackets;
455 typedef check<int> check_type;
457 check_type&& cr = static_cast<check_type&&>(c);
459 static_assert(check_type::value == 201103L, "C++11 compiler");],,
460 ac_cv_cxx_compile_cxx11_native=yes, ac_cv_cxx_compile_cxx11_native=no)
464 AC_CACHE_CHECK(if g++ supports C++11 features with -std=c++11,
465 ac_cv_cxx_compile_cxx11_cxx,
468 ac_save_CXXFLAGS="$CXXFLAGS"
469 CXXFLAGS="$CXXFLAGS -std=c++11"
471 template <typename T>
474 static constexpr T value{ __cplusplus };
477 typedef check<check<bool>> right_angle_brackets;
482 typedef check<int> check_type;
484 check_type&& cr = static_cast<check_type&&>(c);
486 static_assert(check_type::value == 201103L, "C++11 compiler");],,
487 ac_cv_cxx_compile_cxx11_cxx=yes, ac_cv_cxx_compile_cxx11_cxx=no)
488 CXXFLAGS="$ac_save_CXXFLAGS"
492 AC_CACHE_CHECK(if g++ supports C++11 features with -std=gnu++11,
493 ac_cv_cxx_compile_cxx11_gxx,
496 ac_save_CXXFLAGS="$CXXFLAGS"
497 CXXFLAGS="$CXXFLAGS -std=gnu++11"
499 template <typename T>
502 static constexpr T value{ __cplusplus };
505 typedef check<check<bool>> right_angle_brackets;
510 typedef check<int> check_type;
512 check_type&& cr = static_cast<check_type&&>(c);
514 static_assert(check_type::value == 201103L, "C++11 compiler");],,
515 ac_cv_cxx_compile_cxx11_gxx=yes, ac_cv_cxx_compile_cxx11_gxx=no)
516 CXXFLAGS="$ac_save_CXXFLAGS"
520 if test "$ac_cv_cxx_compile_cxx11_native" = yes ||
521 test "$ac_cv_cxx_compile_cxx11_cxx" = yes ||
522 test "$ac_cv_cxx_compile_cxx11_gxx" = yes; then
523 AC_DEFINE(HAVE_STDCXX_11,,[Define if g++ supports C++11 features. ])
529 <para>Check for library coverage of the C++2011 standard.
530 (Some library headers are commented out in this check, they are
531 not currently provided by libstdc++).
535 # AC_HEADER_STDCXX_11
536 AC_DEFUN([AC_HEADER_STDCXX_11], [
537 AC_CACHE_CHECK(for ISO C++11 include files,
539 [AC_REQUIRE([AC_COMPILE_STDCXX_11])
542 ac_save_CXXFLAGS="$CXXFLAGS"
543 CXXFLAGS="$CXXFLAGS -std=gnu++11"
546 #include <cassert>
547 #include <ccomplex>
548 #include <cctype>
549 #include <cerrno>
550 #include <cfenv>
551 #include <cfloat>
552 #include <cinttypes>
553 #include <ciso646>
554 #include <climits>
555 #include <clocale>
556 #include <cmath>
557 #include <csetjmp>
558 #include <csignal>
559 #include <cstdalign>
560 #include <cstdarg>
561 #include <cstdbool>
562 #include <cstddef>
563 #include <cstdint>
564 #include <cstdio>
565 #include <cstdlib>
566 #include <cstring>
567 #include <ctgmath>
568 #include <ctime>
569 // #include <cuchar>
570 #include <cwchar>
571 #include <cwctype>
573 #include <algorithm>
574 #include <array>
575 #include <atomic>
576 #include <bitset>
577 #include <chrono>
578 // #include <codecvt>
579 #include <complex>
580 #include <condition_variable>
581 #include <deque>
582 #include <exception>
583 #include <forward_list>
584 #include <fstream>
585 #include <functional>
586 #include <future>
587 #include <initializer_list>
588 #include <iomanip>
590 #include <iosfwd>
591 #include <iostream>
592 #include <istream>
593 #include <iterator>
594 #include <limits>
595 #include <list>
596 #include <locale>
598 #include <memory>
599 #include <mutex>
601 #include <numeric>
602 #include <ostream>
603 #include <queue>
604 #include <random>
605 #include <ratio>
606 #include <regex>
607 #include <scoped_allocator>
609 #include <sstream>
610 #include <stack>
611 #include <stdexcept>
612 #include <streambuf>
613 #include <string>
614 #include <system_error>
615 #include <thread>
616 #include <tuple>
617 #include <typeindex>
618 #include <typeinfo>
619 #include <type_traits>
620 #include <unordered_map>
621 #include <unordered_set>
622 #include <utility>
623 #include <valarray>
624 #include <vector>
626 ac_cv_cxx_stdcxx_11=yes, ac_cv_cxx_stdcxx_11=no)
628 CXXFLAGS="$ac_save_CXXFLAGS"
630 if test "$ac_cv_cxx_stdcxx_11" = yes; then
631 AC_DEFINE(STDCXX_11_HEADERS,,[Define if ISO C++11 header files are present. ])
636 <para>As is the case for TR1 support, these autoconf macros can be made for a finer-grained, per-header-file check. For
637 <filename class="headerfile"><unordered_map></filename>
641 # AC_HEADER_UNORDERED_MAP
642 AC_DEFUN([AC_HEADER_UNORDERED_MAP], [
643 AC_CACHE_CHECK(for unordered_map,
644 ac_cv_cxx_unordered_map,
645 [AC_REQUIRE([AC_COMPILE_STDCXX_11])
648 ac_save_CXXFLAGS="$CXXFLAGS"
649 CXXFLAGS="$CXXFLAGS -std=gnu++11"
650 AC_TRY_COMPILE([#include <unordered_map>], [using std::unordered_map;],
651 ac_cv_cxx_unordered_map=yes, ac_cv_cxx_unordered_map=no)
652 CXXFLAGS="$ac_save_CXXFLAGS"
655 if test "$ac_cv_cxx_unordered_map" = yes; then
656 AC_DEFINE(HAVE_UNORDERED_MAP,,[Define if unordered_map is present. ])
662 # AC_HEADER_UNORDERED_SET
663 AC_DEFUN([AC_HEADER_UNORDERED_SET], [
664 AC_CACHE_CHECK(for unordered_set,
665 ac_cv_cxx_unordered_set,
666 [AC_REQUIRE([AC_COMPILE_STDCXX_11])
669 ac_save_CXXFLAGS="$CXXFLAGS"
670 CXXFLAGS="$CXXFLAGS -std=gnu++11"
671 AC_TRY_COMPILE([#include <unordered_set>], [using std::unordered_set;],
672 ac_cv_cxx_unordered_set=yes, ac_cv_cxx_unordered_set=no)
673 CXXFLAGS="$ac_save_CXXFLAGS"
676 if test "$ac_cv_cxx_unordered_set" = yes; then
677 AC_DEFINE(HAVE_UNORDERED_SET,,[Define if unordered_set is present. ])
683 Some C++11 features first appeared in GCC 4.3 and could be enabled by
684 <option>-std=c++0x</option> and <option>-std=gnu++0x</option> for GCC
685 releases which pre-date the 2011 standard. Those C++11 features and GCC's
686 support for them were still changing until the 2011 standard was finished,
687 but the autoconf checks above could be extended to test for incomplete
688 C++11 support with <option>-std=c++0x</option> and
689 <option>-std=gnu++0x</option>.
694 <section xml:id="backwards.third.iterator_type"><info><title>
695 <code>Container::iterator_type</code> is not necessarily <code>Container::value_type*</code>
700 This is a change in behavior from older versions. Now, most
701 <type>iterator_type</type> typedefs in container classes are POD
702 objects, not <type>value_type</type> pointers.