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> 765 contains a derived class called 766 <classname>__gnu_cxx::stdio_filebuf</classname>. 767 This class can be constructed from a C <code>FILE*</code> or a file 768 descriptor, and provides the <code>fd()</code> function. 769 </para> 770 771<para> 772 For another example of this, refer to 773 <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.josuttis.com/cppcode/fdstream.html">fdstream example</link> 774 by Nicolai Josuttis. 775</para> 776</section> 777 778<section xml:id="backwards.third.support_cxx98"><info><title> 779Support for C++98 dialect. 780</title></info> 781 782 783<para>Check for complete library coverage of the C++1998/2003 standard. 784</para> 785 786<programlisting> 787# AC_HEADER_STDCXX_98 788AC_DEFUN([AC_HEADER_STDCXX_98], [ 789 AC_CACHE_CHECK(for ISO C++ 98 include files, 790 ac_cv_cxx_stdcxx_98, 791 [AC_LANG_SAVE 792 AC_LANG_CPLUSPLUS 793 AC_TRY_COMPILE([ 794 #include <cassert> 795 #include <cctype> 796 #include <cerrno> 797 #include <cfloat> 798 #include <ciso646> 799 #include <climits> 800 #include <clocale> 801 #include <cmath> 802 #include <csetjmp> 803 #include <csignal> 804 #include <cstdarg> 805 #include <cstddef> 806 #include <cstdio> 807 #include <cstdlib> 808 #include <cstring> 809 #include <ctime> 810 811 #include <algorithm> 812 #include <bitset> 813 #include <complex> 814 #include <deque> 815 #include <exception> 816 #include <fstream> 817 #include <functional> 818 #include <iomanip> 819 #include <ios> 820 #include <iosfwd> 821 #include <iostream> 822 #include <istream> 823 #include <iterator> 824 #include <limits> 825 #include <list> 826 #include <locale> 827 #include <map> 828 #include <memory> 829 #include <new> 830 #include <numeric> 831 #include <ostream> 832 #include <queue> 833 #include <set> 834 #include <sstream> 835 #include <stack> 836 #include <stdexcept> 837 #include <streambuf> 838 #include <string> 839 #include <typeinfo> 840 #include <utility> 841 #include <valarray> 842 #include <vector> 843 ],, 844 ac_cv_cxx_stdcxx_98=yes, ac_cv_cxx_stdcxx_98=no) 845 AC_LANG_RESTORE 846 ]) 847 if test "$ac_cv_cxx_stdcxx_98" = yes; then 848 AC_DEFINE(STDCXX_98_HEADERS,,[Define if ISO C++ 1998 header files are present. ]) 849 fi 850]) 851</programlisting> 852</section> 853 854<section xml:id="backwards.third.support_tr1"><info><title> 855Support for C++TR1 dialect. 856</title></info> 857 858 859<para>Check for library coverage of the TR1 standard. 860</para> 861 862<programlisting> 863# AC_HEADER_STDCXX_TR1 864AC_DEFUN([AC_HEADER_STDCXX_TR1], [ 865 AC_CACHE_CHECK(for ISO C++ TR1 include files, 866 ac_cv_cxx_stdcxx_tr1, 867 [AC_LANG_SAVE 868 AC_LANG_CPLUSPLUS 869 AC_TRY_COMPILE([ 870 #include <tr1/array> 871 #include <tr1/ccomplex> 872 #include <tr1/cctype> 873 #include <tr1/cfenv> 874 #include <tr1/cfloat> 875 #include <tr1/cinttypes> 876 #include <tr1/climits> 877 #include <tr1/cmath> 878 #include <tr1/complex> 879 #include <tr1/cstdarg> 880 #include <tr1/cstdbool> 881 #include <tr1/cstdint> 882 #include <tr1/cstdio> 883 #include <tr1/cstdlib> 884 #include <tr1/ctgmath> 885 #include <tr1/ctime> 886 #include <tr1/cwchar> 887 #include <tr1/cwctype> 888 #include <tr1/functional> 889 #include <tr1/memory> 890 #include <tr1/random> 891 #include <tr1/regex> 892 #include <tr1/tuple> 893 #include <tr1/type_traits> 894 #include <tr1/unordered_set> 895 #include <tr1/unordered_map> 896 #include <tr1/utility> 897 ],, 898 ac_cv_cxx_stdcxx_tr1=yes, ac_cv_cxx_stdcxx_tr1=no) 899 AC_LANG_RESTORE 900 ]) 901 if test "$ac_cv_cxx_stdcxx_tr1" = yes; then 902 AC_DEFINE(STDCXX_TR1_HEADERS,,[Define if ISO C++ TR1 header files are present. ]) 903 fi 904]) 905</programlisting> 906 907<para>An alternative is to check just for specific TR1 includes, such as <unordered_map> and <unordered_set>. 908</para> 909 910<programlisting> 911# AC_HEADER_TR1_UNORDERED_MAP 912AC_DEFUN([AC_HEADER_TR1_UNORDERED_MAP], [ 913 AC_CACHE_CHECK(for tr1/unordered_map, 914 ac_cv_cxx_tr1_unordered_map, 915 [AC_LANG_SAVE 916 AC_LANG_CPLUSPLUS 917 AC_TRY_COMPILE([#include <tr1/unordered_map>], [using std::tr1::unordered_map;], 918 ac_cv_cxx_tr1_unordered_map=yes, ac_cv_cxx_tr1_unordered_map=no) 919 AC_LANG_RESTORE 920 ]) 921 if test "$ac_cv_cxx_tr1_unordered_map" = yes; then 922 AC_DEFINE(HAVE_TR1_UNORDERED_MAP,,[Define if tr1/unordered_map is present. ]) 923 fi 924]) 925</programlisting> 926 927<programlisting> 928# AC_HEADER_TR1_UNORDERED_SET 929AC_DEFUN([AC_HEADER_TR1_UNORDERED_SET], [ 930 AC_CACHE_CHECK(for tr1/unordered_set, 931 ac_cv_cxx_tr1_unordered_set, 932 [AC_LANG_SAVE 933 AC_LANG_CPLUSPLUS 934 AC_TRY_COMPILE([#include <tr1/unordered_set>], [using std::tr1::unordered_set;], 935 ac_cv_cxx_tr1_unordered_set=yes, ac_cv_cxx_tr1_unordered_set=no) 936 AC_LANG_RESTORE 937 ]) 938 if test "$ac_cv_cxx_tr1_unordered_set" = yes; then 939 AC_DEFINE(HAVE_TR1_UNORDERED_SET,,[Define if tr1/unordered_set is present. ]) 940 fi 941]) 942</programlisting> 943</section> 944 945 946<section xml:id="backwards.third.support_cxx11"><info><title> 947Support for C++11 dialect. 948</title></info> 949 950 951<para>Check for baseline language coverage in the compiler for the C++11 standard. 952</para> 953 954<programlisting> 955# AC_COMPILE_STDCXX_11 956AC_DEFUN([AC_COMPILE_STDCXX_11], [ 957 AC_CACHE_CHECK(if g++ supports C++11 features without additional flags, 958 ac_cv_cxx_compile_cxx11_native, 959 [AC_LANG_SAVE 960 AC_LANG_CPLUSPLUS 961 AC_TRY_COMPILE([ 962 template <typename T> 963 struct check final 964 { 965 static constexpr T value{ __cplusplus }; 966 }; 967 968 typedef check<check<bool>> right_angle_brackets; 969 970 int a; 971 decltype(a) b; 972 973 typedef check<int> check_type; 974 check_type c{}; 975 check_type&& cr = static_cast<check_type&&>(c); 976 977 static_assert(check_type::value == 201103L, "C++11 compiler");],, 978 ac_cv_cxx_compile_cxx11_native=yes, ac_cv_cxx_compile_cxx11_native=no) 979 AC_LANG_RESTORE 980 ]) 981 982 AC_CACHE_CHECK(if g++ supports C++11 features with -std=c++11, 983 ac_cv_cxx_compile_cxx11_cxx, 984 [AC_LANG_SAVE 985 AC_LANG_CPLUSPLUS 986 ac_save_CXXFLAGS="$CXXFLAGS" 987 CXXFLAGS="$CXXFLAGS -std=c++11" 988 AC_TRY_COMPILE([ 989 template <typename T> 990 struct check final 991 { 992 static constexpr T value{ __cplusplus }; 993 }; 994 995 typedef check<check<bool>> right_angle_brackets; 996 997 int a; 998 decltype(a) b; 999 1000 typedef check<int> check_type; 1001 check_type c{}; 1002 check_type&& cr = static_cast<check_type&&>(c); 1003 1004 static_assert(check_type::value == 201103L, "C++11 compiler");],, 1005 ac_cv_cxx_compile_cxx11_cxx=yes, ac_cv_cxx_compile_cxx11_cxx=no) 1006 CXXFLAGS="$ac_save_CXXFLAGS" 1007 AC_LANG_RESTORE 1008 ]) 1009 1010 AC_CACHE_CHECK(if g++ supports C++11 features with -std=gnu++11, 1011 ac_cv_cxx_compile_cxx11_gxx, 1012 [AC_LANG_SAVE 1013 AC_LANG_CPLUSPLUS 1014 ac_save_CXXFLAGS="$CXXFLAGS" 1015 CXXFLAGS="$CXXFLAGS -std=gnu++11" 1016 AC_TRY_COMPILE([ 1017 template <typename T> 1018 struct check final 1019 { 1020 static constexpr T value{ __cplusplus }; 1021 }; 1022 1023 typedef check<check<bool>> right_angle_brackets; 1024 1025 int a; 1026 decltype(a) b; 1027 1028 typedef check<int> check_type; 1029 check_type c{}; 1030 check_type&& cr = static_cast<check_type&&>(c); 1031 1032 static_assert(check_type::value == 201103L, "C++11 compiler");],, 1033 ac_cv_cxx_compile_cxx11_gxx=yes, ac_cv_cxx_compile_cxx11_gxx=no) 1034 CXXFLAGS="$ac_save_CXXFLAGS" 1035 AC_LANG_RESTORE 1036 ]) 1037 1038 if test "$ac_cv_cxx_compile_cxx11_native" = yes || 1039 test "$ac_cv_cxx_compile_cxx11_cxx" = yes || 1040 test "$ac_cv_cxx_compile_cxx11_gxx" = yes; then 1041 AC_DEFINE(HAVE_STDCXX_11,,[Define if g++ supports C++11 features. ]) 1042 fi 1043]) 1044</programlisting> 1045 1046 1047<para>Check for library coverage of the C++2011 standard. 1048 (Some library headers are commented out in this check, they are 1049 not currently provided by libstdc++). 1050</para> 1051 1052<programlisting> 1053# AC_HEADER_STDCXX_11 1054AC_DEFUN([AC_HEADER_STDCXX_11], [ 1055 AC_CACHE_CHECK(for ISO C++11 include files, 1056 ac_cv_cxx_stdcxx_11, 1057 [AC_REQUIRE([AC_COMPILE_STDCXX_11]) 1058 AC_LANG_SAVE 1059 AC_LANG_CPLUSPLUS 1060 ac_save_CXXFLAGS="$CXXFLAGS" 1061 CXXFLAGS="$CXXFLAGS -std=gnu++11" 1062 1063 AC_TRY_COMPILE([ 1064 #include <cassert> 1065 #include <ccomplex> 1066 #include <cctype> 1067 #include <cerrno> 1068 #include <cfenv> 1069 #include <cfloat> 1070 #include <cinttypes> 1071 #include <ciso646> 1072 #include <climits> 1073 #include <clocale> 1074 #include <cmath> 1075 #include <csetjmp> 1076 #include <csignal> 1077 #include <cstdalign> 1078 #include <cstdarg> 1079 #include <cstdbool> 1080 #include <cstddef> 1081 #include <cstdint> 1082 #include <cstdio> 1083 #include <cstdlib> 1084 #include <cstring> 1085 #include <ctgmath> 1086 #include <ctime> 1087 // #include <cuchar> 1088 #include <cwchar> 1089 #include <cwctype> 1090 1091 #include <algorithm> 1092 #include <array> 1093 #include <atomic> 1094 #include <bitset> 1095 #include <chrono> 1096 // #include <codecvt> 1097 #include <complex> 1098 #include <condition_variable> 1099 #include <deque> 1100 #include <exception> 1101 #include <forward_list> 1102 #include <fstream> 1103 #include <functional> 1104 #include <future> 1105 #include <initializer_list> 1106 #include <iomanip> 1107 #include <ios> 1108 #include <iosfwd> 1109 #include <iostream> 1110 #include <istream> 1111 #include <iterator> 1112 #include <limits> 1113 #include <list> 1114 #include <locale> 1115 #include <map> 1116 #include <memory> 1117 #include <mutex> 1118 #include <new> 1119 #include <numeric> 1120 #include <ostream> 1121 #include <queue> 1122 #include <random> 1123 #include <ratio> 1124 #include <regex> 1125 #include <scoped_allocator> 1126 #include <set> 1127 #include <sstream> 1128 #include <stack> 1129 #include <stdexcept> 1130 #include <streambuf> 1131 #include <string> 1132 #include <system_error> 1133 #include <thread> 1134 #include <tuple> 1135 #include <typeindex> 1136 #include <typeinfo> 1137 #include <type_traits> 1138 #include <unordered_map> 1139 #include <unordered_set> 1140 #include <utility> 1141 #include <valarray> 1142 #include <vector> 1143 ],, 1144 ac_cv_cxx_stdcxx_11=yes, ac_cv_cxx_stdcxx_11=no) 1145 AC_LANG_RESTORE 1146 CXXFLAGS="$ac_save_CXXFLAGS" 1147 ]) 1148 if test "$ac_cv_cxx_stdcxx_11" = yes; then 1149 AC_DEFINE(STDCXX_11_HEADERS,,[Define if ISO C++11 header files are present. ]) 1150 fi 1151]) 1152</programlisting> 1153 1154<para>As is the case for TR1 support, these autoconf macros can be made for a finer-grained, per-header-file check. For 1155<filename class="headerfile"><unordered_map></filename> 1156</para> 1157 1158<programlisting> 1159# AC_HEADER_UNORDERED_MAP 1160AC_DEFUN([AC_HEADER_UNORDERED_MAP], [ 1161 AC_CACHE_CHECK(for unordered_map, 1162 ac_cv_cxx_unordered_map, 1163 [AC_REQUIRE([AC_COMPILE_STDCXX_11]) 1164 AC_LANG_SAVE 1165 AC_LANG_CPLUSPLUS 1166 ac_save_CXXFLAGS="$CXXFLAGS" 1167 CXXFLAGS="$CXXFLAGS -std=gnu++11" 1168 AC_TRY_COMPILE([#include <unordered_map>], [using std::unordered_map;], 1169 ac_cv_cxx_unordered_map=yes, ac_cv_cxx_unordered_map=no) 1170 CXXFLAGS="$ac_save_CXXFLAGS" 1171 AC_LANG_RESTORE 1172 ]) 1173 if test "$ac_cv_cxx_unordered_map" = yes; then 1174 AC_DEFINE(HAVE_UNORDERED_MAP,,[Define if unordered_map is present. ]) 1175 fi 1176]) 1177</programlisting> 1178 1179<programlisting> 1180# AC_HEADER_UNORDERED_SET 1181AC_DEFUN([AC_HEADER_UNORDERED_SET], [ 1182 AC_CACHE_CHECK(for unordered_set, 1183 ac_cv_cxx_unordered_set, 1184 [AC_REQUIRE([AC_COMPILE_STDCXX_11]) 1185 AC_LANG_SAVE 1186 AC_LANG_CPLUSPLUS 1187 ac_save_CXXFLAGS="$CXXFLAGS" 1188 CXXFLAGS="$CXXFLAGS -std=gnu++11" 1189 AC_TRY_COMPILE([#include <unordered_set>], [using std::unordered_set;], 1190 ac_cv_cxx_unordered_set=yes, ac_cv_cxx_unordered_set=no) 1191 CXXFLAGS="$ac_save_CXXFLAGS" 1192 AC_LANG_RESTORE 1193 ]) 1194 if test "$ac_cv_cxx_unordered_set" = yes; then 1195 AC_DEFINE(HAVE_UNORDERED_SET,,[Define if unordered_set is present. ]) 1196 fi 1197]) 1198</programlisting> 1199 1200<para> 1201 Some C++11 features first appeared in GCC 4.3 and could be enabled by 1202 <option>-std=c++0x</option> and <option>-std=gnu++0x</option> for GCC 1203 releases which pre-date the 2011 standard. Those C++11 features and GCC's 1204 support for them were still changing until the 2011 standard was finished, 1205 but the autoconf checks above could be extended to test for incomplete 1206 C++11 support with <option>-std=c++0x</option> and 1207 <option>-std=gnu++0x</option>. 1208</para> 1209 1210</section> 1211 1212<section xml:id="backwards.third.iterator_type"><info><title> 1213 <code>Container::iterator_type</code> is not necessarily <code>Container::value_type*</code> 1214</title></info> 1215 1216 1217<para> 1218 This is a change in behavior from older versions. Now, most 1219 <type>iterator_type</type> typedefs in container classes are POD 1220 objects, not <type>value_type</type> pointers. 1221</para> 1222</section> 1223 1224</section> 1225 1226<bibliography xml:id="backwards.biblio"><info><title>Bibliography</title></info> 1227 1228 1229 <biblioentry> 1230 <title> 1231 <link xmlns:xlink="http://www.w3.org/1999/xlink" 1232 xlink:href="http://www.kegel.com/gcc/gcc4.html"> 1233 Migrating to GCC 4.1 1234 </link> 1235 </title> 1236 1237 <author><personname><firstname>Dan</firstname><surname>Kegel</surname></personname></author> 1238 </biblioentry> 1239 1240 <biblioentry> 1241 <title> 1242 <link xmlns:xlink="http://www.w3.org/1999/xlink" 1243 xlink:href="https://lists.debian.org/debian-gcc/2006/03/msg00405.html"> 1244 Building the Whole Debian Archive with GCC 4.1: A Summary 1245 </link> 1246 </title> 1247 <author><personname><firstname>Martin</firstname><surname>Michlmayr</surname></personname></author> 1248 </biblioentry> 1249 1250 <biblioentry> 1251 <title> 1252 <link xmlns:xlink="http://www.w3.org/1999/xlink" 1253 xlink:href="http://annwm.lbl.gov/~leggett/Atlas/gcc-3.2.html"> 1254 Migration guide for GCC-3.2 1255 </link> 1256 </title> 1257 1258 </biblioentry> 1259 1260</bibliography> 1261 1262</section> 1263