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"?> 4 5<info><title>Backwards Compatibility</title> 6 <keywordset> 7 <keyword>ISO C++</keyword> 8 <keyword>backwards</keyword> 9 </keywordset> 10</info> 11 12 13 14<section xml:id="backwards.first"><info><title>First</title></info> 15 16 17<para>The first generation GNU C++ library was called libg++. It was a 18separate GNU project, although reliably paired with GCC. Rumors imply 19that it had a working relationship with at least two kinds of 20dinosaur. 21</para> 22 23<para>Some background: libg++ was designed and created when there was no 24ISO standard to provide guidance. Classes like linked lists are now 25provided for by <classname>list<T></classname> and do not need to be 26created by <function>genclass</function>. (For that matter, templates exist 27now and are well-supported, whereas genclass (mostly) predates them.) 28</para> 29 30<para>There are other classes in libg++ that are not specified in the 31ISO Standard (e.g., statistical analysis). While there are a lot of 32really useful things that are used by a lot of people, the Standards 33Committee couldn't include everything, and so a lot of those 34<quote>obvious</quote> classes didn't get included. 35</para> 36 37<para>Known Issues include many of the limitations of its immediate ancestor.</para> 38 39<para>Portability notes and known implementation limitations are as follows.</para> 40 41<section xml:id="backwards.first.ios_base"><info><title>No <code>ios_base</code></title></info> 42 43 44<para> At least some older implementations don't have <code>std::ios_base</code>, so you should use <code>std::ios::badbit</code>, <code>std::ios::failbit</code> and <code>std::ios::eofbit</code> and <code>std::ios::goodbit</code>. 45</para> 46</section> 47 48<section xml:id="backwards.first.cout_cin"><info><title>No <code>cout</code> in <filename class="headerfile"><ostream.h></filename>, no <code>cin</code> in <filename class="headerfile"><istream.h></filename></title></info> 49 50 51<para> 52 In earlier versions of the standard, 53 <filename class="headerfile"><fstream.h></filename>, 54 <filename class="headerfile"><ostream.h></filename> 55 and <filename class="headerfile"><istream.h></filename> 56 used to define 57 <code>cout</code>, <code>cin</code> and so on. ISO C++ specifies that one needs to include 58 <filename class="headerfile"><iostream></filename> 59 explicitly to get the required definitions. 60 </para> 61<para> Some include adjustment may be required.</para> 62 63<para>This project is no longer maintained or supported, and the sources 64archived. For the desperate, 65the <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://gcc.gnu.org/extensions.html">GCC extensions 66page</link> describes where to find the last libg++ source. The code is 67considered replaced and rewritten. 68</para> 69</section> 70</section> 71 72<section xml:id="backwards.second"><info><title>Second</title></info> 73 74 75<para> 76 The second generation GNU C++ library was called libstdc++, or 77 libstdc++-v2. It spans the time between libg++ and pre-ISO C++ 78 standardization and is usually associated with the following GCC 79 releases: egcs 1.x, gcc 2.95, and gcc 2.96. 80</para> 81 82<para> 83 The STL portions of this library are based on SGI/HP STL release 3.11. 84</para> 85 86<para> 87 This project is no longer maintained or supported, and the sources 88 archived. The code is considered replaced and rewritten. 89</para> 90 91<para> 92 Portability notes and known implementation limitations are as follows. 93</para> 94 95<section xml:id="backwards.second.std"><info><title>Namespace <code>std::</code> not supported</title></info> 96 97 98 <para> 99 Some care is required to support C++ compiler and or library 100 implementation that do not have the standard library in 101 <code>namespace std</code>. 102 </para> 103 104 <para> 105 The following sections list some possible solutions to support compilers 106 that cannot ignore <code>std::</code>-qualified names. 107 </para> 108 109 <para> 110 First, see if the compiler has a flag for this. Namespace 111 back-portability-issues are generally not a problem for g++ 112 compilers that do not have libstdc++ in <code>std::</code>, as the 113 compilers use <option>-fno-honor-std</option> (ignore 114 <code>std::</code>, <code>:: = std::</code>) by default. That is, 115 the responsibility for enabling or disabling <code>std::</code> is 116 on the user; the maintainer does not have to care about it. This 117 probably applies to some other compilers as well. 118 </para> 119 120 <para> 121 Second, experiment with a variety of pre-processor tricks. 122 </para> 123 124 <para> 125 By defining <code>std</code> as a macro, fully-qualified namespace 126 calls become global. Volia. 127 </para> 128 129<programlisting> 130#ifdef WICKEDLY_OLD_COMPILER 131# define std 132#endif 133</programlisting> 134 135 <para> 136 Thanks to Juergen Heinzl who posted this solution on gnu.gcc.help. 137 </para> 138 139 <para> 140 Another pre-processor based approach is to define a macro 141 <code>NAMESPACE_STD</code>, which is defined to either 142 <quote> </quote> or <quote>std</quote> based on a compile-type 143 test. On GNU systems, this can be done with autotools by means of 144 an autoconf test (see below) for <code>HAVE_NAMESPACE_STD</code>, 145 then using that to set a value for the <code>NAMESPACE_STD</code> 146 macro. At that point, one is able to use 147 <code>NAMESPACE_STD::string</code>, which will evaluate to 148 <code>std::string</code> or <code>::string</code> (i.e., in the 149 global namespace on systems that do not put <code>string</code> in 150 <code>std::</code>). 151 </para> 152 153<programlisting> 154dnl @synopsis AC_CXX_NAMESPACE_STD 155dnl 156dnl If the compiler supports namespace std, define 157dnl HAVE_NAMESPACE_STD. 158dnl 159dnl @category Cxx 160dnl @author Todd Veldhuizen 161dnl @author Luc Maisonobe <luc@spaceroots.org> 162dnl @version 2004-02-04 163dnl @license AllPermissive 164AC_DEFUN([AC_CXX_NAMESPACE_STD], [ 165 AC_CACHE_CHECK(if g++ supports namespace std, 166 ac_cv_cxx_have_std_namespace, 167 [AC_LANG_SAVE 168 AC_LANG_CPLUSPLUS 169 AC_TRY_COMPILE([#include <iostream> 170 std::istream& is = std::cin;],, 171 ac_cv_cxx_have_std_namespace=yes, ac_cv_cxx_have_std_namespace=no) 172 AC_LANG_RESTORE 173 ]) 174 if test "$ac_cv_cxx_have_std_namespace" = yes; then 175 AC_DEFINE(HAVE_NAMESPACE_STD,,[Define if g++ supports namespace std. ]) 176 fi 177]) 178</programlisting> 179</section> 180 181<section xml:id="backwards.second.iterators"><info><title>Illegal iterator usage</title></info> 182 183<para> 184 The following illustrate implementation-allowed illegal iterator 185 use, and then correct use. 186</para> 187 188<itemizedlist> 189 <listitem> 190 <para> 191 you cannot do <code>ostream::operator<<(iterator)</code> 192 to print the address of the iterator => use 193 <code>operator<< &*iterator</code> instead 194 </para> 195 </listitem> 196 <listitem> 197 <para> 198 you cannot clear an iterator's reference (<code>iterator = 199 0</code>) => use <code>iterator = iterator_type();</code> 200 </para> 201 </listitem> 202 <listitem> 203 <para> 204 <code>if (iterator)</code> won't work any more => use 205 <code>if (iterator != iterator_type())</code> 206 </para> 207 </listitem> 208</itemizedlist> 209</section> 210 211<section xml:id="backwards.second.isspace"><info><title><code>isspace</code> from <filename class="headerfile"><cctype></filename> is a macro 212 </title></info> 213 214 215 <para> 216 Glibc 2.0.x and 2.1.x define <filename class="headerfile"><ctype.h></filename> functionality as macros 217 (isspace, isalpha etc.). 218 </para> 219 220 <para> 221 This implementations of libstdc++, however, keep these functions 222 as macros, and so it is not back-portable to use fully qualified 223 names. For example: 224 </para> 225 226<programlisting> 227#include <cctype> 228int main() { std::isspace('X'); } 229</programlisting> 230 231<para> 232 Results in something like this: 233</para> 234 235<programlisting> 236std:: (__ctype_b[(int) ( ( 'X' ) )] & (unsigned short int) _ISspace ) ; 237</programlisting> 238 239<para> 240 A solution is to modify a header-file so that the compiler tells 241 <filename class="headerfile"><ctype.h></filename> to define functions 242 instead of macros: 243</para> 244 245<programlisting> 246// This keeps isalnum, et al from being propagated as macros. 247#if __linux__ 248# define __NO_CTYPE 1 249#endif 250</programlisting> 251 252<para> 253 Then, include <filename class="headerfile"><ctype.h></filename> 254</para> 255 256<para> 257 Another problem arises if you put a <code>using namespace 258 std;</code> declaration at the top, and include 259 <filename class="headerfile"><ctype.h></filename>. This will 260 result in ambiguities between the definitions in the global namespace 261 (<filename class="headerfile"><ctype.h></filename>) and the 262 definitions in namespace <code>std::</code> 263 (<code><cctype></code>). 264</para> 265</section> 266 267<section xml:id="backwards.second.at"><info><title>No <code>vector::at</code>, <code>deque::at</code>, <code>string::at</code></title></info> 268 269 270<para> 271 One solution is to add an autoconf-test for this: 272</para> 273 274<programlisting> 275AC_MSG_CHECKING(for container::at) 276AC_TRY_COMPILE( 277[ 278#include <vector> 279#include <deque> 280#include <string> 281 282using namespace std; 283], 284[ 285deque<int> test_deque(3); 286test_deque.at(2); 287vector<int> test_vector(2); 288test_vector.at(1); 289string test_string(<quote>test_string</quote>); 290test_string.at(3); 291], 292[AC_MSG_RESULT(yes) 293AC_DEFINE(HAVE_CONTAINER_AT)], 294[AC_MSG_RESULT(no)]) 295</programlisting> 296 297<para> 298 If you are using other (non-GNU) compilers it might be a good idea 299 to check for <code>string::at</code> separately. 300</para> 301 302</section> 303 304<section xml:id="backwards.second.eof"><info><title>No <code>std::char_traits<char>::eof</code></title></info> 305 306 307<para> 308 Use some kind of autoconf test, plus this: 309</para> 310 311<programlisting> 312#ifdef HAVE_CHAR_TRAITS 313#define CPP_EOF std::char_traits<char>::eof() 314#else 315#define CPP_EOF EOF 316#endif 317</programlisting> 318 319</section> 320 321<section xml:id="backwards.second.stringclear"><info><title>No <code>string::clear</code></title></info> 322 323 324<para> 325 There are two functions for deleting the contents of a string: 326 <code>clear</code> and <code>erase</code> (the latter returns the 327 string). 328</para> 329 330<programlisting> 331void 332clear() { _M_mutate(0, this->size(), 0); } 333</programlisting> 334 335<programlisting> 336basic_string& 337erase(size_type __pos = 0, size_type __n = npos) 338{ 339 return this->replace(_M_check(__pos), _M_fold(__pos, __n), 340 _M_data(), _M_data()); 341} 342</programlisting> 343 344<para> 345 Unfortunately, <code>clear</code> is not implemented in this 346 version, so you should use <code>erase</code> (which is probably 347 faster than <code>operator=(charT*)</code>). 348</para> 349</section> 350 351<section xml:id="backwards.second.ostreamform_istreamscan"><info><title> 352 Removal of <code>ostream::form</code> and <code>istream::scan</code> 353 extensions 354</title></info> 355 356 357<para> 358 These are no longer supported. Please use stringstreams instead. 359</para> 360</section> 361 362<section xml:id="backwards.second.stringstreams"><info><title>No <code>basic_stringbuf</code>, <code>basic_stringstream</code></title></info> 363 364 365<para> 366 Although the ISO standard <code>i/ostringstream</code>-classes are 367 provided, (<filename class="headerfile"><sstream></filename>), for 368 compatibility with older implementations the pre-ISO 369 <code>i/ostrstream</code> (<filename class="headerfile"><strstream></filename>) interface is also provided, 370 with these caveats: 371</para> 372 373<itemizedlist> 374 <listitem> 375 <para> 376 <code>strstream</code> is considered to be deprecated 377 </para> 378 </listitem> 379 <listitem> 380 <para> 381 <code>strstream</code> is limited to <code>char</code> 382 </para> 383 </listitem> 384 <listitem> 385 <para> 386 with <code>ostringstream</code> you don't have to take care of 387 terminating the string or freeing its memory 388 </para> 389 </listitem> 390 <listitem> 391 <para> 392 <code>istringstream</code> can be re-filled (clear(); 393 str(input);) 394 </para> 395 </listitem> 396</itemizedlist> 397 398<para> 399 You can then use output-stringstreams like this: 400</para> 401 402<programlisting> 403#ifdef HAVE_SSTREAM 404# include <sstream> 405#else 406# include <strstream> 407#endif 408 409#ifdef HAVE_SSTREAM 410 std::ostringstream oss; 411#else 412 std::ostrstream oss; 413#endif 414 415oss << "Name=" << m_name << ", number=" << m_number << std::endl; 416... 417#ifndef HAVE_SSTREAM 418 oss << std::ends; // terminate the char*-string 419#endif 420 421// str() returns char* for ostrstream and a string for ostringstream 422// this also causes ostrstream to think that the buffer's memory 423// is yours 424m_label.set_text(oss.str()); 425#ifndef HAVE_SSTREAM 426 // let the ostrstream take care of freeing the memory 427 oss.freeze(false); 428#endif 429</programlisting> 430 431<para> 432 Input-stringstreams can be used similarly: 433</para> 434 435<programlisting> 436std::string input; 437... 438#ifdef HAVE_SSTREAM 439std::istringstream iss(input); 440#else 441std::istrstream iss(input.c_str()); 442#endif 443 444int i; 445iss >> i; 446</programlisting> 447 448<para> One (the only?) restriction is that an istrstream cannot be re-filled: 449</para> 450 451<programlisting> 452std::istringstream iss(numerator); 453iss >> m_num; 454// this is not possible with istrstream 455iss.clear(); 456iss.str(denominator); 457iss >> m_den; 458</programlisting> 459 460<para> 461If you don't care about speed, you can put these conversions in 462 a template-function: 463</para> 464<programlisting> 465template <class X> 466void fromString(const string& input, X& any) 467{ 468#ifdef HAVE_SSTREAM 469std::istringstream iss(input); 470#else 471std::istrstream iss(input.c_str()); 472#endif 473X temp; 474iss >> temp; 475if (iss.fail()) 476throw runtime_error(..) 477any = temp; 478} 479</programlisting> 480 481<para> 482 Another example of using stringstreams is in <link linkend="strings.string.shrink">this howto</link>. 483</para> 484 485<para> There is additional information in the libstdc++-v2 info files, in 486particular <quote>info iostream</quote>. 487</para> 488</section> 489 490<section xml:id="backwards.second.wchar"><info><title>Little or no wide character support</title></info> 491 492 <para> 493 Classes <classname>wstring</classname> and 494 <classname>char_traits<wchar_t></classname> are 495 not supported. 496 </para> 497</section> 498 499<section xml:id="backwards.second.iostream_templates"><info><title>No templatized iostreams</title></info> 500 501 <para> 502 Classes <classname>wfilebuf</classname> and 503 <classname>wstringstream</classname> are not supported. 504 </para> 505</section> 506 507<section xml:id="backwards.second.thread_safety"><info><title>Thread safety issues</title></info> 508 509 510 <para> 511 Earlier GCC releases had a somewhat different approach to 512 threading configuration and proper compilation. Before GCC 3.0, 513 configuration of the threading model was dictated by compiler 514 command-line options and macros (both of which were somewhat 515 thread-implementation and port-specific). There were no 516 guarantees related to being able to link code compiled with one 517 set of options and macro setting with another set. 518 </para> 519 520 <para> 521 For GCC 3.0, configuration of the threading model used with 522 libraries and user-code is performed when GCC is configured and 523 built using the --enable-threads and --disable-threads options. 524 The ABI is stable for symbol name-mangling and limited functional 525 compatibility exists between code compiled under different 526 threading models. 527 </para> 528 529 <para> 530 The libstdc++ library has been designed so that it can be used in 531 multithreaded applications (with libstdc++-v2 this was only true 532 of the STL parts.) The first problem is finding a 533 <emphasis>fast</emphasis> method of implementation portable to 534 all platforms. Due to historical reasons, some of the library is 535 written against per-CPU-architecture spinlocks and other parts 536 against the gthr.h abstraction layer which is provided by gcc. A 537 minor problem that pops up every so often is different 538 interpretations of what "thread-safe" means for a 539 library (not a general program). We currently use the <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://web.archive.org/web/20171225062613/http://www.sgi.com/tech/stl/thread_safety.html">same 540 definition that SGI</link> uses for their STL subset. However, 541 the exception for read-only containers only applies to the STL 542 components. This definition is widely-used and something similar 543 will be used in the next version of the C++ standard library. 544 </para> 545 546 <para> 547 Here is a small link farm to threads (no pun) in the mail 548 archives that discuss the threading problem. Each link is to the 549 first relevant message in the thread; from there you can use 550 "Thread Next" to move down the thread. This farm is in 551 latest-to-oldest order. 552 </para> 553 554 <itemizedlist> 555 <listitem> 556 <para> 557 Our threading expert Loren gives a breakdown of <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://gcc.gnu.org/ml/libstdc++/2001-10/msg00024.html">the 558 six situations involving threads</link> for the 3.0 559 release series. 560 </para> 561 </listitem> 562 <listitem> 563 <para> 564 <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://gcc.gnu.org/ml/libstdc++/2001-05/msg00384.html"> 565 This message</link> inspired a recent updating of issues with 566 threading and the SGI STL library. It also contains some 567 example POSIX-multithreaded STL code. 568 </para> 569 </listitem> 570 </itemizedlist> 571 572 <para> 573 (A large selection of links to older messages has been removed; 574 many of the messages from 1999 were lost in a disk crash, and the 575 few people with access to the backup tapes have been too swamped 576 with work to restore them. Many of the points have been 577 superseded anyhow.) 578 </para> 579</section> 580 581</section> 582 583<section xml:id="backwards.third"><info><title>Third</title></info> 584 585 586<para> The third generation GNU C++ library is called libstdc++, or 587libstdc++-v3. 588</para> 589 590 <para>The subset commonly known as the Standard Template Library 591 (clauses 23 through 25, mostly) is adapted from the final release 592 of the SGI STL (version 3.3), with extensive changes. 593 </para> 594 595 <para>A more formal description of the V3 goals can be found in the 596 official <link linkend="contrib.design_notes">design document</link>. 597 </para> 598 599<para>Portability notes and known implementation limitations are as follows.</para> 600 601<section xml:id="backwards.third.headers"><info><title>Pre-ISO headers removed</title></info> 602 603 604<para> The pre-ISO C++ headers 605 (<filename class="headerfile"><iostream.h></filename>, 606 <filename class="headerfile"><defalloc.h></filename> etc.) are 607 not supported. 608</para> 609 610 <para>For those of you new to ISO C++ (welcome, time travelers!), the 611 ancient pre-ISO headers have new names. 612 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 613 the difference between <xxx> and <xxx.h> headers?</link>. 614 </para> 615 616<para>Porting between pre-ISO headers and ISO headers is simple: headers 617like <filename class="headerfile"><vector.h></filename> can be replaced with <filename class="headerfile"><vector></filename> and a using 618directive <code>using namespace std;</code> can be put at the global 619scope. This should be enough to get this code compiling, assuming the 620other usage is correct. 621</para> 622</section> 623 624<section xml:id="backwards.third.hash"><info><title>Extension headers hash_map, hash_set moved to ext or backwards</title></info> 625 626 627 <para>At this time most of the features of the SGI STL extension have been 628 replaced by standardized libraries. 629 In particular, the <classname>unordered_map</classname> and 630 <classname>unordered_set</classname> containers of TR1 and C++ 2011 631 are suitable replacements for the non-standard 632 <classname>hash_map</classname> and <classname>hash_set</classname> 633 containers in the SGI STL. 634 </para> 635<para> Header files <filename class="headerfile"><hash_map></filename> and <filename class="headerfile"><hash_set></filename> moved 636to <filename class="headerfile"><ext/hash_map></filename> and <filename class="headerfile"><ext/hash_set></filename>, 637respectively. At the same time, all types in these files are enclosed 638in <code>namespace __gnu_cxx</code>. Later versions deprecate 639these files, and suggest using TR1's <filename class="headerfile"><unordered_map></filename> 640and <filename class="headerfile"><unordered_set></filename> instead. 641</para> 642 643 <para>The extensions are no longer in the global or <code>std</code> 644 namespaces, instead they are declared in the <code>__gnu_cxx</code> 645 namespace. For maximum portability, consider defining a namespace 646 alias to use to talk about extensions, e.g.: 647 </para> 648 <programlisting> 649 #ifdef __GNUC__ 650 #if __GNUC__ < 3 651 #include <hash_map.h> 652 namespace extension { using ::hash_map; }; // inherit globals 653 #else 654 #include <backward/hash_map> 655 #if __GNUC__ == 3 && __GNUC_MINOR__ == 0 656 namespace extension = std; // GCC 3.0 657 #else 658 namespace extension = ::__gnu_cxx; // GCC 3.1 and later 659 #endif 660 #endif 661 #else // ... there are other compilers, right? 662 namespace extension = std; 663 #endif 664 665 extension::hash_map<int,int> my_map; 666 </programlisting> 667 <para>This is a bit cleaner than defining typedefs for all the 668 instantiations you might need. 669 </para> 670 671 672<para>The following autoconf tests check for working HP/SGI hash containers. 673</para> 674 675<programlisting> 676# AC_HEADER_EXT_HASH_MAP 677AC_DEFUN([AC_HEADER_EXT_HASH_MAP], [ 678 AC_CACHE_CHECK(for ext/hash_map, 679 ac_cv_cxx_ext_hash_map, 680 [AC_LANG_SAVE 681 AC_LANG_CPLUSPLUS 682 ac_save_CXXFLAGS="$CXXFLAGS" 683 CXXFLAGS="$CXXFLAGS -Werror" 684 AC_TRY_COMPILE([#include <ext/hash_map>], [using __gnu_cxx::hash_map;], 685 ac_cv_cxx_ext_hash_map=yes, ac_cv_cxx_ext_hash_map=no) 686 CXXFLAGS="$ac_save_CXXFLAGS" 687 AC_LANG_RESTORE 688 ]) 689 if test "$ac_cv_cxx_ext_hash_map" = yes; then 690 AC_DEFINE(HAVE_EXT_HASH_MAP,,[Define if ext/hash_map is present. ]) 691 fi 692]) 693</programlisting> 694 695<programlisting> 696# AC_HEADER_EXT_HASH_SET 697AC_DEFUN([AC_HEADER_EXT_HASH_SET], [ 698 AC_CACHE_CHECK(for ext/hash_set, 699 ac_cv_cxx_ext_hash_set, 700 [AC_LANG_SAVE 701 AC_LANG_CPLUSPLUS 702 ac_save_CXXFLAGS="$CXXFLAGS" 703 CXXFLAGS="$CXXFLAGS -Werror" 704 AC_TRY_COMPILE([#include <ext/hash_set>], [using __gnu_cxx::hash_set;], 705 ac_cv_cxx_ext_hash_set=yes, ac_cv_cxx_ext_hash_set=no) 706 CXXFLAGS="$ac_save_CXXFLAGS" 707 AC_LANG_RESTORE 708 ]) 709 if test "$ac_cv_cxx_ext_hash_set" = yes; then 710 AC_DEFINE(HAVE_EXT_HASH_SET,,[Define if ext/hash_set is present. ]) 711 fi 712]) 713</programlisting> 714</section> 715 716<section xml:id="backwards.third.nocreate_noreplace"><info><title>No <code>ios::nocreate/ios::noreplace</code>. 717</title></info> 718 719 720<para>Historically these flags were used with iostreams to control whether 721new files are created or not when opening a file stream, similar to the 722<code>O_CREAT</code> and <code>O_EXCL</code> flags for the 723<function>open(2)</function> system call. Because iostream modes correspond 724to <function>fopen(3)</function> modes these flags are not supported. 725For input streams a new file will not be created anyway, so 726<code>ios::nocreate</code> is not needed. 727For output streams, a new file will be created if it does not exist, which is 728consistent with the behaviour of <function>fopen</function>. 729</para> 730 731<para>When one of these flags is needed a possible alternative is to attempt 732to open the file using <type>std::ifstream</type> first to determine whether 733the file already exists or not. This may not be reliable however, because 734whether the file exists or not could change between opening the 735<type>std::istream</type> and re-opening with an output stream. If you need 736to check for existence and open a file as a single operation then you will 737need to use OS-specific facilities outside the C++ standard library, such 738as <function>open(2)</function>. 739</para> 740</section> 741 742<section xml:id="backwards.third.streamattach"><info><title> 743No <code>stream::attach(int fd)</code> 744</title></info> 745 746 747<para> 748 Phil Edwards writes: It was considered and rejected for the ISO 749 standard. Not all environments use file descriptors. Of those 750 that do, not all of them use integers to represent them. 751 </para> 752 753<para> 754 For a portable solution (among systems which use 755 file descriptors), you need to implement a subclass of 756 <code>std::streambuf</code> (or 757 <code>std::basic_streambuf<..></code>) which opens a file 758 given a descriptor, and then pass an instance of this to the 759 stream-constructor. 760 </para> 761 762<para> 763 An extension is available that implements this. 764 <filename class="headerfile"><ext/stdio_filebuf.h></filename> contains a derived class called 765 <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a00074.html"><code>__gnu_cxx::stdio_filebuf</code></link>. 766 This class can be constructed from a C <code>FILE*</code> or a file 767 descriptor, and provides the <code>fd()</code> function. 768 </para> 769 770<para> 771 For another example of this, refer to 772 <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.josuttis.com/cppcode/fdstream.html">fdstream example</link> 773 by Nicolai Josuttis. 774</para> 775</section> 776 777<section xml:id="backwards.third.support_cxx98"><info><title> 778Support for C++98 dialect. 779</title></info> 780 781 782<para>Check for complete library coverage of the C++1998/2003 standard. 783</para> 784 785<programlisting> 786# AC_HEADER_STDCXX_98 787AC_DEFUN([AC_HEADER_STDCXX_98], [ 788 AC_CACHE_CHECK(for ISO C++ 98 include files, 789 ac_cv_cxx_stdcxx_98, 790 [AC_LANG_SAVE 791 AC_LANG_CPLUSPLUS 792 AC_TRY_COMPILE([ 793 #include <cassert> 794 #include <cctype> 795 #include <cerrno> 796 #include <cfloat> 797 #include <ciso646> 798 #include <climits> 799 #include <clocale> 800 #include <cmath> 801 #include <csetjmp> 802 #include <csignal> 803 #include <cstdarg> 804 #include <cstddef> 805 #include <cstdio> 806 #include <cstdlib> 807 #include <cstring> 808 #include <ctime> 809 810 #include <algorithm> 811 #include <bitset> 812 #include <complex> 813 #include <deque> 814 #include <exception> 815 #include <fstream> 816 #include <functional> 817 #include <iomanip> 818 #include <ios> 819 #include <iosfwd> 820 #include <iostream> 821 #include <istream> 822 #include <iterator> 823 #include <limits> 824 #include <list> 825 #include <locale> 826 #include <map> 827 #include <memory> 828 #include <new> 829 #include <numeric> 830 #include <ostream> 831 #include <queue> 832 #include <set> 833 #include <sstream> 834 #include <stack> 835 #include <stdexcept> 836 #include <streambuf> 837 #include <string> 838 #include <typeinfo> 839 #include <utility> 840 #include <valarray> 841 #include <vector> 842 ],, 843 ac_cv_cxx_stdcxx_98=yes, ac_cv_cxx_stdcxx_98=no) 844 AC_LANG_RESTORE 845 ]) 846 if test "$ac_cv_cxx_stdcxx_98" = yes; then 847 AC_DEFINE(STDCXX_98_HEADERS,,[Define if ISO C++ 1998 header files are present. ]) 848 fi 849]) 850</programlisting> 851</section> 852 853<section xml:id="backwards.third.support_tr1"><info><title> 854Support for C++TR1 dialect. 855</title></info> 856 857 858<para>Check for library coverage of the TR1 standard. 859</para> 860 861<programlisting> 862# AC_HEADER_STDCXX_TR1 863AC_DEFUN([AC_HEADER_STDCXX_TR1], [ 864 AC_CACHE_CHECK(for ISO C++ TR1 include files, 865 ac_cv_cxx_stdcxx_tr1, 866 [AC_LANG_SAVE 867 AC_LANG_CPLUSPLUS 868 AC_TRY_COMPILE([ 869 #include <tr1/array> 870 #include <tr1/ccomplex> 871 #include <tr1/cctype> 872 #include <tr1/cfenv> 873 #include <tr1/cfloat> 874 #include <tr1/cinttypes> 875 #include <tr1/climits> 876 #include <tr1/cmath> 877 #include <tr1/complex> 878 #include <tr1/cstdarg> 879 #include <tr1/cstdbool> 880 #include <tr1/cstdint> 881 #include <tr1/cstdio> 882 #include <tr1/cstdlib> 883 #include <tr1/ctgmath> 884 #include <tr1/ctime> 885 #include <tr1/cwchar> 886 #include <tr1/cwctype> 887 #include <tr1/functional> 888 #include <tr1/memory> 889 #include <tr1/random> 890 #include <tr1/regex> 891 #include <tr1/tuple> 892 #include <tr1/type_traits> 893 #include <tr1/unordered_set> 894 #include <tr1/unordered_map> 895 #include <tr1/utility> 896 ],, 897 ac_cv_cxx_stdcxx_tr1=yes, ac_cv_cxx_stdcxx_tr1=no) 898 AC_LANG_RESTORE 899 ]) 900 if test "$ac_cv_cxx_stdcxx_tr1" = yes; then 901 AC_DEFINE(STDCXX_TR1_HEADERS,,[Define if ISO C++ TR1 header files are present. ]) 902 fi 903]) 904</programlisting> 905 906<para>An alternative is to check just for specific TR1 includes, such as <unordered_map> and <unordered_set>. 907</para> 908 909<programlisting> 910# AC_HEADER_TR1_UNORDERED_MAP 911AC_DEFUN([AC_HEADER_TR1_UNORDERED_MAP], [ 912 AC_CACHE_CHECK(for tr1/unordered_map, 913 ac_cv_cxx_tr1_unordered_map, 914 [AC_LANG_SAVE 915 AC_LANG_CPLUSPLUS 916 AC_TRY_COMPILE([#include <tr1/unordered_map>], [using std::tr1::unordered_map;], 917 ac_cv_cxx_tr1_unordered_map=yes, ac_cv_cxx_tr1_unordered_map=no) 918 AC_LANG_RESTORE 919 ]) 920 if test "$ac_cv_cxx_tr1_unordered_map" = yes; then 921 AC_DEFINE(HAVE_TR1_UNORDERED_MAP,,[Define if tr1/unordered_map is present. ]) 922 fi 923]) 924</programlisting> 925 926<programlisting> 927# AC_HEADER_TR1_UNORDERED_SET 928AC_DEFUN([AC_HEADER_TR1_UNORDERED_SET], [ 929 AC_CACHE_CHECK(for tr1/unordered_set, 930 ac_cv_cxx_tr1_unordered_set, 931 [AC_LANG_SAVE 932 AC_LANG_CPLUSPLUS 933 AC_TRY_COMPILE([#include <tr1/unordered_set>], [using std::tr1::unordered_set;], 934 ac_cv_cxx_tr1_unordered_set=yes, ac_cv_cxx_tr1_unordered_set=no) 935 AC_LANG_RESTORE 936 ]) 937 if test "$ac_cv_cxx_tr1_unordered_set" = yes; then 938 AC_DEFINE(HAVE_TR1_UNORDERED_SET,,[Define if tr1/unordered_set is present. ]) 939 fi 940]) 941</programlisting> 942</section> 943 944 945<section xml:id="backwards.third.support_cxx11"><info><title> 946Support for C++11 dialect. 947</title></info> 948 949 950<para>Check for baseline language coverage in the compiler for the C++11 standard. 951</para> 952 953<programlisting> 954# AC_COMPILE_STDCXX_11 955AC_DEFUN([AC_COMPILE_STDCXX_11], [ 956 AC_CACHE_CHECK(if g++ supports C++11 features without additional flags, 957 ac_cv_cxx_compile_cxx11_native, 958 [AC_LANG_SAVE 959 AC_LANG_CPLUSPLUS 960 AC_TRY_COMPILE([ 961 template <typename T> 962 struct check final 963 { 964 static constexpr T value{ __cplusplus }; 965 }; 966 967 typedef check<check<bool>> right_angle_brackets; 968 969 int a; 970 decltype(a) b; 971 972 typedef check<int> check_type; 973 check_type c{}; 974 check_type&& cr = static_cast<check_type&&>(c); 975 976 static_assert(check_type::value == 201103L, "C++11 compiler");],, 977 ac_cv_cxx_compile_cxx11_native=yes, ac_cv_cxx_compile_cxx11_native=no) 978 AC_LANG_RESTORE 979 ]) 980 981 AC_CACHE_CHECK(if g++ supports C++11 features with -std=c++11, 982 ac_cv_cxx_compile_cxx11_cxx, 983 [AC_LANG_SAVE 984 AC_LANG_CPLUSPLUS 985 ac_save_CXXFLAGS="$CXXFLAGS" 986 CXXFLAGS="$CXXFLAGS -std=c++11" 987 AC_TRY_COMPILE([ 988 template <typename T> 989 struct check final 990 { 991 static constexpr T value{ __cplusplus }; 992 }; 993 994 typedef check<check<bool>> right_angle_brackets; 995 996 int a; 997 decltype(a) b; 998 999 typedef check<int> check_type; 1000 check_type c{}; 1001 check_type&& cr = static_cast<check_type&&>(c); 1002 1003 static_assert(check_type::value == 201103L, "C++11 compiler");],, 1004 ac_cv_cxx_compile_cxx11_cxx=yes, ac_cv_cxx_compile_cxx11_cxx=no) 1005 CXXFLAGS="$ac_save_CXXFLAGS" 1006 AC_LANG_RESTORE 1007 ]) 1008 1009 AC_CACHE_CHECK(if g++ supports C++11 features with -std=gnu++11, 1010 ac_cv_cxx_compile_cxx11_gxx, 1011 [AC_LANG_SAVE 1012 AC_LANG_CPLUSPLUS 1013 ac_save_CXXFLAGS="$CXXFLAGS" 1014 CXXFLAGS="$CXXFLAGS -std=gnu++11" 1015 AC_TRY_COMPILE([ 1016 template <typename T> 1017 struct check final 1018 { 1019 static constexpr T value{ __cplusplus }; 1020 }; 1021 1022 typedef check<check<bool>> right_angle_brackets; 1023 1024 int a; 1025 decltype(a) b; 1026 1027 typedef check<int> check_type; 1028 check_type c{}; 1029 check_type&& cr = static_cast<check_type&&>(c); 1030 1031 static_assert(check_type::value == 201103L, "C++11 compiler");],, 1032 ac_cv_cxx_compile_cxx11_gxx=yes, ac_cv_cxx_compile_cxx11_gxx=no) 1033 CXXFLAGS="$ac_save_CXXFLAGS" 1034 AC_LANG_RESTORE 1035 ]) 1036 1037 if test "$ac_cv_cxx_compile_cxx11_native" = yes || 1038 test "$ac_cv_cxx_compile_cxx11_cxx" = yes || 1039 test "$ac_cv_cxx_compile_cxx11_gxx" = yes; then 1040 AC_DEFINE(HAVE_STDCXX_11,,[Define if g++ supports C++11 features. ]) 1041 fi 1042]) 1043</programlisting> 1044 1045 1046<para>Check for library coverage of the C++2011 standard. 1047 (Some library headers are commented out in this check, they are 1048 not currently provided by libstdc++). 1049</para> 1050 1051<programlisting> 1052# AC_HEADER_STDCXX_11 1053AC_DEFUN([AC_HEADER_STDCXX_11], [ 1054 AC_CACHE_CHECK(for ISO C++11 include files, 1055 ac_cv_cxx_stdcxx_11, 1056 [AC_REQUIRE([AC_COMPILE_STDCXX_11]) 1057 AC_LANG_SAVE 1058 AC_LANG_CPLUSPLUS 1059 ac_save_CXXFLAGS="$CXXFLAGS" 1060 CXXFLAGS="$CXXFLAGS -std=gnu++11" 1061 1062 AC_TRY_COMPILE([ 1063 #include <cassert> 1064 #include <ccomplex> 1065 #include <cctype> 1066 #include <cerrno> 1067 #include <cfenv> 1068 #include <cfloat> 1069 #include <cinttypes> 1070 #include <ciso646> 1071 #include <climits> 1072 #include <clocale> 1073 #include <cmath> 1074 #include <csetjmp> 1075 #include <csignal> 1076 #include <cstdalign> 1077 #include <cstdarg> 1078 #include <cstdbool> 1079 #include <cstddef> 1080 #include <cstdint> 1081 #include <cstdio> 1082 #include <cstdlib> 1083 #include <cstring> 1084 #include <ctgmath> 1085 #include <ctime> 1086 // #include <cuchar> 1087 #include <cwchar> 1088 #include <cwctype> 1089 1090 #include <algorithm> 1091 #include <array> 1092 #include <atomic> 1093 #include <bitset> 1094 #include <chrono> 1095 // #include <codecvt> 1096 #include <complex> 1097 #include <condition_variable> 1098 #include <deque> 1099 #include <exception> 1100 #include <forward_list> 1101 #include <fstream> 1102 #include <functional> 1103 #include <future> 1104 #include <initializer_list> 1105 #include <iomanip> 1106 #include <ios> 1107 #include <iosfwd> 1108 #include <iostream> 1109 #include <istream> 1110 #include <iterator> 1111 #include <limits> 1112 #include <list> 1113 #include <locale> 1114 #include <map> 1115 #include <memory> 1116 #include <mutex> 1117 #include <new> 1118 #include <numeric> 1119 #include <ostream> 1120 #include <queue> 1121 #include <random> 1122 #include <ratio> 1123 #include <regex> 1124 #include <scoped_allocator> 1125 #include <set> 1126 #include <sstream> 1127 #include <stack> 1128 #include <stdexcept> 1129 #include <streambuf> 1130 #include <string> 1131 #include <system_error> 1132 #include <thread> 1133 #include <tuple> 1134 #include <typeindex> 1135 #include <typeinfo> 1136 #include <type_traits> 1137 #include <unordered_map> 1138 #include <unordered_set> 1139 #include <utility> 1140 #include <valarray> 1141 #include <vector> 1142 ],, 1143 ac_cv_cxx_stdcxx_11=yes, ac_cv_cxx_stdcxx_11=no) 1144 AC_LANG_RESTORE 1145 CXXFLAGS="$ac_save_CXXFLAGS" 1146 ]) 1147 if test "$ac_cv_cxx_stdcxx_11" = yes; then 1148 AC_DEFINE(STDCXX_11_HEADERS,,[Define if ISO C++11 header files are present. ]) 1149 fi 1150]) 1151</programlisting> 1152 1153<para>As is the case for TR1 support, these autoconf macros can be made for a finer-grained, per-header-file check. For 1154<filename class="headerfile"><unordered_map></filename> 1155</para> 1156 1157<programlisting> 1158# AC_HEADER_UNORDERED_MAP 1159AC_DEFUN([AC_HEADER_UNORDERED_MAP], [ 1160 AC_CACHE_CHECK(for unordered_map, 1161 ac_cv_cxx_unordered_map, 1162 [AC_REQUIRE([AC_COMPILE_STDCXX_11]) 1163 AC_LANG_SAVE 1164 AC_LANG_CPLUSPLUS 1165 ac_save_CXXFLAGS="$CXXFLAGS" 1166 CXXFLAGS="$CXXFLAGS -std=gnu++11" 1167 AC_TRY_COMPILE([#include <unordered_map>], [using std::unordered_map;], 1168 ac_cv_cxx_unordered_map=yes, ac_cv_cxx_unordered_map=no) 1169 CXXFLAGS="$ac_save_CXXFLAGS" 1170 AC_LANG_RESTORE 1171 ]) 1172 if test "$ac_cv_cxx_unordered_map" = yes; then 1173 AC_DEFINE(HAVE_UNORDERED_MAP,,[Define if unordered_map is present. ]) 1174 fi 1175]) 1176</programlisting> 1177 1178<programlisting> 1179# AC_HEADER_UNORDERED_SET 1180AC_DEFUN([AC_HEADER_UNORDERED_SET], [ 1181 AC_CACHE_CHECK(for unordered_set, 1182 ac_cv_cxx_unordered_set, 1183 [AC_REQUIRE([AC_COMPILE_STDCXX_11]) 1184 AC_LANG_SAVE 1185 AC_LANG_CPLUSPLUS 1186 ac_save_CXXFLAGS="$CXXFLAGS" 1187 CXXFLAGS="$CXXFLAGS -std=gnu++11" 1188 AC_TRY_COMPILE([#include <unordered_set>], [using std::unordered_set;], 1189 ac_cv_cxx_unordered_set=yes, ac_cv_cxx_unordered_set=no) 1190 CXXFLAGS="$ac_save_CXXFLAGS" 1191 AC_LANG_RESTORE 1192 ]) 1193 if test "$ac_cv_cxx_unordered_set" = yes; then 1194 AC_DEFINE(HAVE_UNORDERED_SET,,[Define if unordered_set is present. ]) 1195 fi 1196]) 1197</programlisting> 1198 1199<para> 1200 Some C++11 features first appeared in GCC 4.3 and could be enabled by 1201 <option>-std=c++0x</option> and <option>-std=gnu++0x</option> for GCC 1202 releases which pre-date the 2011 standard. Those C++11 features and GCC's 1203 support for them were still changing until the 2011 standard was finished, 1204 but the autoconf checks above could be extended to test for incomplete 1205 C++11 support with <option>-std=c++0x</option> and 1206 <option>-std=gnu++0x</option>. 1207</para> 1208 1209</section> 1210 1211<section xml:id="backwards.third.iterator_type"><info><title> 1212 <code>Container::iterator_type</code> is not necessarily <code>Container::value_type*</code> 1213</title></info> 1214 1215 1216<para> 1217 This is a change in behavior from older versions. Now, most 1218 <type>iterator_type</type> typedefs in container classes are POD 1219 objects, not <type>value_type</type> pointers. 1220</para> 1221</section> 1222 1223</section> 1224 1225<bibliography xml:id="backwards.biblio"><info><title>Bibliography</title></info> 1226 1227 1228 <biblioentry> 1229 <title> 1230 <link xmlns:xlink="http://www.w3.org/1999/xlink" 1231 xlink:href="http://www.kegel.com/gcc/gcc4.html"> 1232 Migrating to GCC 4.1 1233 </link> 1234 </title> 1235 1236 <author><personname><firstname>Dan</firstname><surname>Kegel</surname></personname></author> 1237 </biblioentry> 1238 1239 <biblioentry> 1240 <title> 1241 <link xmlns:xlink="http://www.w3.org/1999/xlink" 1242 xlink:href="https://lists.debian.org/debian-gcc/2006/03/msg00405.html"> 1243 Building the Whole Debian Archive with GCC 4.1: A Summary 1244 </link> 1245 </title> 1246 <author><personname><firstname>Martin</firstname><surname>Michlmayr</surname></personname></author> 1247 </biblioentry> 1248 1249 <biblioentry> 1250 <title> 1251 <link xmlns:xlink="http://www.w3.org/1999/xlink" 1252 xlink:href="http://annwm.lbl.gov/~leggett/Atlas/gcc-3.2.html"> 1253 Migration guide for GCC-3.2 1254 </link> 1255 </title> 1256 1257 </biblioentry> 1258 1259</bibliography> 1260 1261</section> 1262