gcc 3.0 vs code from Josuttis' book (problems)

Peter Schmid schmid@snake.iap.physik.tu-darmstadt.de
Mon Jun 11 08:03:00 GMT 2001


After applying the following patch which fixes, mostly small or even
cosmetic but genuine, coding errors, gcc 3.0 20010611 can compile most
of the examples of Nicolai Josuttis' book "The C++ Standard Library",
even when -pedantic is added to the command line.

diff -cpr orig/cont/bitset2.cpp neu/cont/bitset2.cpp
*** orig/cont/bitset2.cpp	Wed Dec 27 16:32:40 2000
--- neu/cont/bitset2.cpp	Sat Mar 10 20:18:43 2001
*************** int main()
*** 27,33 ****
           << endl;
  
      cout << "10,000,000 with 24 bits: "
!          << bitset<24>(1e7) << endl;
  
      /* transform binary representation into integral number
       */
--- 27,33 ----
           << endl;
  
      cout << "10,000,000 with 24 bits: "
!          << bitset<24>(10000000) << endl;
  
      /* transform binary representation into integral number
       */
diff -cpr orig/cont/deque1.cpp neu/cont/deque1.cpp
*** orig/cont/deque1.cpp	Wed Dec 27 16:32:40 2000
--- neu/cont/deque1.cpp	Mon Jun 11 16:12:08 2001
*************** int main()
*** 34,40 ****
      coll.pop_back();
  
      // insert ``another'' into every element but the first
!     for (int i=1; i<coll.size(); ++i) {
          coll[i] = "another " + coll[i];
      }
  
--- 34,40 ----
      coll.pop_back();
  
      // insert ``another'' into every element but the first
!     for (size_t i=1; i<coll.size(); ++i) {
          coll[i] = "another " + coll[i];
      }
  
diff -cpr orig/cont/refsem1.cpp neu/cont/refsem1.cpp
*** orig/cont/refsem1.cpp	Wed Dec 27 16:32:41 2000
--- neu/cont/refsem1.cpp	Sat Mar 10 20:19:36 2001
*************** int main()
*** 34,40 ****
       * - same order in coll1
       * - reverse order in coll2
       */
!     for (int i=0; i<sizeof(values)/sizeof(values[0]); ++i) {
          IntPtr ptr(new int(values[i]));
          coll1.push_back(ptr);
          coll2.push_front(ptr);
--- 34,40 ----
       * - same order in coll1
       * - reverse order in coll2
       */
!     for (size_t i=0; i<sizeof(values)/sizeof(values[0]); ++i) {
          IntPtr ptr(new int(values[i]));
          coll1.push_back(ptr);
          coll2.push_front(ptr);
diff -cpr orig/fo/compose10.hpp neu/fo/compose10.hpp
*** orig/fo/compose10.hpp	Wed Dec 27 16:32:42 2000
--- neu/fo/compose10.hpp	Sat Mar 10 17:37:21 2001
***************
*** 15,21 ****
   */
  template <class OP1, class OP2>
  class compose_f_g_t
!  : public boost::nullary_function<typename OP1::result_type>
  {
    private:
      OP1 op1;    // process: op1(op2())
--- 15,21 ----
   */
  template <class OP1, class OP2>
  class compose_f_g_t
!  : public nullary_function<typename OP1::result_type>
  {
    private:
      OP1 op1;    // process: op1(op2())
diff -cpr orig/fo/fopow1.cpp neu/fo/fopow1.cpp
*** orig/fo/fopow1.cpp	Wed Dec 27 16:32:42 2000
--- neu/fo/fopow1.cpp	Mon Jun 11 16:12:08 2001
*************** int main()
*** 27,39 ****
  
      // print 3 raised to the power of all elements
      transform (coll.begin(), coll.end(),         // source
!                ostream_iterator<int>(cout," "),  // destination
                 bind1st(fopow<float,int>(),3));   // operation
      cout << endl;
  
      // print all elements raised to the power of 3
      transform (coll.begin(), coll.end(),         // source
!                ostream_iterator<int>(cout," "),  // destination
                 bind2nd(fopow<float,int>(),3));   // operation
      cout << endl;
  }
--- 27,39 ----
  
      // print 3 raised to the power of all elements
      transform (coll.begin(), coll.end(),         // source
!                ostream_iterator<float>(cout," "),  // destination
                 bind1st(fopow<float,int>(),3));   // operation
      cout << endl;
  
      // print all elements raised to the power of 3
      transform (coll.begin(), coll.end(),         // source
!                ostream_iterator<float>(cout," "),  // destination
                 bind2nd(fopow<float,int>(),3));   // operation
      cout << endl;
  }
diff -cpr orig/io/outbuf1.hpp neu/io/outbuf1.hpp
*** orig/io/outbuf1.hpp	Wed Dec 27 16:32:48 2000
--- neu/io/outbuf1.hpp	Mon Jun 11 16:11:39 2001
*************** class outbuf : public std::streambuf
*** 21,27 ****
      virtual int_type overflow (int_type c) {
          if (c != EOF) {
              // convert lowercase to uppercase
!             c = std::toupper(c,getloc());
  
              // and write the character to the standard output
              if (putchar(c) == EOF) {
--- 21,27 ----
      virtual int_type overflow (int_type c) {
          if (c != EOF) {
              // convert lowercase to uppercase
!             c = std::toupper(static_cast<char>(c),getloc());
  
              // and write the character to the standard output
              if (putchar(c) == EOF) {
diff -cpr orig/io/outbuf1x.hpp neu/io/outbuf1x.hpp
*** orig/io/outbuf1x.hpp	Wed Dec 27 16:32:48 2000
--- neu/io/outbuf1x.hpp	Mon Jun 11 16:11:41 2001
***************
*** 12,28 ****
  #include <locale>
  #include <cstdio>
  
! template <class charT, class traits = char_traits<charT> >
  class basic_outbuf : public std::basic_streambuf<charT,traits>
  {
    protected:
      /* central output function
       * - print characters in uppercase mode
       */
!     virtual int_type overflow (int_type c) {
          if (!traits::eq_int_type(c,traits::eof())) {
              // convert lowercase to uppercase
!             c = std::toupper(c,getloc());
  
              // and write the character to the standard output
              if (putchar(c) == EOF) {
--- 12,29 ----
  #include <locale>
  #include <cstdio>
  
! template <class charT, class traits = std::char_traits<charT> >
  class basic_outbuf : public std::basic_streambuf<charT,traits>
  {
    protected:
      /* central output function
       * - print characters in uppercase mode
       */
!     virtual std::basic_streambuf<charT,traits>::int_type overflow
!     (std::basic_streambuf<charT,traits>::int_type c) {
          if (!traits::eq_int_type(c,traits::eof())) {
              // convert lowercase to uppercase
!             c = std::toupper(static_cast<wchar_t>(c),getloc());
  
              // and write the character to the standard output
              if (putchar(c) == EOF) {
diff -cpr orig/iter/itercat.cpp neu/iter/itercat.cpp
*** orig/iter/itercat.cpp	Wed Dec 27 16:32:42 2000
--- neu/iter/itercat.cpp	Sat Mar 10 20:22:15 2001
*************** int main()
*** 38,44 ****
     /* print all elements
      * - NOTE: uses operator [] instead of operator *
      */
!    for (int i=0; i<coll.size(); ++i) {
         cout << coll.begin()[i] << ' ';
     }
     cout << endl;
--- 38,44 ----
     /* print all elements
      * - NOTE: uses operator [] instead of operator *
      */
!    for (size_t i=0; i<coll.size(); ++i) {
         cout << coll.begin()[i] << ' ';
     }
     cout << endl;
diff -cpr orig/num/gslice1.cpp neu/num/gslice1.cpp
*** orig/num/gslice1.cpp	Wed Dec 27 16:32:47 2000
--- neu/num/gslice1.cpp	Sat Mar 10 20:22:33 2001
*************** using namespace std;
*** 16,22 ****
  template<class T>
  void printValarray3D (const valarray<T>& va, int dim1, int dim2)
  {
!     for (int i=0; i<va.size()/(dim1*dim2); ++i) {
          for (int j=0; j<dim2; ++j) {
              for (int k=0; k<dim1; ++k) {
                  cout << va[i*dim1*dim2+j*dim1+k] << ' ';
--- 16,22 ----
  template<class T>
  void printValarray3D (const valarray<T>& va, int dim1, int dim2)
  {
!     for (size_t i=0; i<va.size()/(dim1*dim2); ++i) {
          for (int j=0; j<dim2; ++j) {
              for (int k=0; k<dim1; ++k) {
                  cout << va[i*dim1*dim2+j*dim1+k] << ' ';
diff -cpr orig/num/indi1.cpp neu/num/indi1.cpp
*** orig/num/indi1.cpp	Wed Dec 27 16:32:47 2000
--- neu/num/indi1.cpp	Sat Mar 10 20:52:00 2001
*************** using namespace std;
*** 16,22 ****
  template<class T>
  void printValarray (const valarray<T>& va, int num)
  {
!     for (int i=0; i<va.size()/num; i++) {
          for (int j=0; j<num; j++) {
              cout << va[i*num+j] << ' ';
          }
--- 16,22 ----
  template<class T>
  void printValarray (const valarray<T>& va, int num)
  {
!     for (size_t i=0; i<va.size()/num; i++) {
          for (int j=0; j<num; j++) {
              cout << va[i*num+j] << ' ';
          }
diff -cpr orig/num/masked1.cpp neu/num/masked1.cpp
*** orig/num/masked1.cpp	Wed Dec 27 16:32:47 2000
--- neu/num/masked1.cpp	Sat Mar 10 20:22:47 2001
*************** using namespace std;
*** 16,22 ****
  template<class T>
  void printValarray (const valarray<T>& va, int num)
  {
!     for (int i=0; i<va.size()/num; ++i) {
          for (int j=0; j<num; ++j) {
              cout << va[i*num+j] << ' ';
          }
--- 16,22 ----
  template<class T>
  void printValarray (const valarray<T>& va, int num)
  {
!     for (size_t i=0; i<va.size()/num; ++i) {
          for (int j=0; j<num; ++j) {
              cout << va[i*num+j] << ' ';
          }
diff -cpr orig/num/slice1.cpp neu/num/slice1.cpp
*** orig/num/slice1.cpp	Wed Dec 27 16:32:47 2000
--- neu/num/slice1.cpp	Sun Mar 11 16:42:50 2001
*************** using namespace std;
*** 16,22 ****
  template<class T>
  void printValarray (const valarray<T>& va, int num)
  {
!     for (int i=0; i<va.size()/num; ++i) {
          for (int j=0; j<num; ++j) {
              cout << va[i*num+j] << ' ';
          }
--- 16,22 ----
  template<class T>
  void printValarray (const valarray<T>& va, int num)
  {
!     for (size_t i=0; i<va.size()/num; ++i) {
          for (int j=0; j<num; ++j) {
              cout << va[i*num+j] << ' ';
          }
*************** int main()
*** 53,61 ****
      va[slice(2,4,3)] *= vb;
  
      printValarray (va, 3);
! 
      // print the square root of the elements in the second row
!     printValarray (sqrt(valarray<double>(va[slice(3,3,1)])), 3);
  
      // double the elements in the third row
      va[slice(2,4,3)] = valarray<double>(va[slice(2,4,3)]) * 2.0;
--- 53,62 ----
      va[slice(2,4,3)] *= vb;
  
      printValarray (va, 3);
!     
      // print the square root of the elements in the second row
!     valarray<double> vc = sqrt(valarray<double>(va[slice(3,3,1)]));
!     printValarray (vc, 3);
  
      // double the elements in the third row
      va[slice(2,4,3)] = valarray<double>(va[slice(2,4,3)]) * 2.0;
diff -cpr orig/num/val1.cpp neu/num/val1.cpp
*** orig/num/val1.cpp	Wed Dec 27 16:32:47 2000
--- neu/num/val1.cpp	Sat Mar 10 20:23:23 2001
*************** using namespace std;
*** 16,22 ****
  template <class T>
  void printValarray (const valarray<T>& va)
  {
!     for (int i=0; i<va.size(); i++) {
          cout << va[i] << ' ';
      }
      cout << endl;
--- 16,22 ----
  template <class T>
  void printValarray (const valarray<T>& va)
  {
!     for (size_t i=0; i<va.size(); i++) {
          cout << va[i] << ' ';
      }
      cout << endl;
diff -cpr orig/num/val2.cpp neu/num/val2.cpp
*** orig/num/val2.cpp	Wed Dec 27 16:32:47 2000
--- neu/num/val2.cpp	Sat Mar 10 20:27:24 2001
*************** using namespace std;
*** 16,22 ****
  template <class T>
  void printValarray (const valarray<T>& va)
  {
!     for (int i=0; i<va.size(); i++) {
          cout << va[i] << ' ';
      }
      cout << endl;
--- 16,22 ----
  template <class T>
  void printValarray (const valarray<T>& va)
  {
!     for (size_t i=0; i<va.size(); i++) {
          cout << va[i] << ' ';
      }
      cout << endl;
*************** int main()
*** 26,32 ****
  {
      // create and initialize valarray with nine elements
      valarray<double> va(9);
!     for (int i=0; i<va.size(); i++) {
          va[i] = i * 1.1;
      }
  
--- 26,32 ----
  {
      // create and initialize valarray with nine elements
      valarray<double> va(9);
!     for (size_t i=0; i<va.size(); i++) {
          va[i] = i * 1.1;
      }
  
*************** int main()
*** 46,53 ****
      printValarray(vb);
  
      // create third valarray as a result of processing both existing valarrays
!     valarray<double> vc;
!     vc = sqrt(va) + vb/2.0 - 1.0;
      
      // print third valarray
      printValarray(vc);
--- 46,52 ----
      printValarray(vb);
  
      // create third valarray as a result of processing both existing valarrays
!     valarray<double> vc = sqrt(va) + vb/2.0 - 1.0;
      
      // print third valarray
      printValarray(vc);
diff -cpr orig/stl/deque1.cpp neu/stl/deque1.cpp
*** orig/stl/deque1.cpp	Wed Dec 27 16:32:38 2000
--- neu/stl/deque1.cpp	Sat Mar 10 20:23:58 2001
*************** int main()
*** 22,28 ****
      }
  
      // print all elements followed by a space
!     for (int i=0; i<coll.size(); ++i) {
          cout << coll[i] << ' ';
      }
      cout << endl;
--- 22,28 ----
      }
  
      // print all elements followed by a space
!     for (size_t i=0; i<coll.size(); ++i) {
          cout << coll[i] << ' ';
      }
      cout << endl;
diff -cpr orig/stl/vector1.cpp neu/stl/vector1.cpp
*** orig/stl/vector1.cpp	Wed Dec 27 16:32:40 2000
--- neu/stl/vector1.cpp	Sat Mar 10 20:56:24 2001
*************** int main()
*** 22,28 ****
      }
  
      // print all elements followed by a space
!     for (int i=0; i<coll.size(); ++i) {
          cout << coll[i] << ' ';
      }
      cout << endl;
--- 22,28 ----
      }
  
      // print all elements followed by a space
!     for (size_t i=0; i<coll.size(); ++i) {
          cout << coll[i] << ' ';
      }
      cout << endl;
diff -cpr orig/string/string2.cpp neu/string/string2.cpp
*** orig/string/string2.cpp	Wed Dec 27 16:32:46 2000
--- neu/string/string2.cpp	Sat Mar 10 20:58:44 2001
***************
*** 12,18 ****
  #include <string>
  using namespace std;
  
! int main (int argc, char** argv)
  {
     const string delims(" \t,.;");
     string line;
--- 12,18 ----
  #include <string>
  using namespace std;
  
! int main ()
  {
     const string delims(" \t,.;");
     string line;


But some problems remain:

I have to apply another patch to work around parser and lookup
problems of gcc 3.0.

diff -cpr orig/algo/generate.cpp neu/algo/generate.cpp
*** orig/algo/generate.cpp	Wed Dec 27 16:32:44 2000
--- neu/algo/generate.cpp	Tue Mar 27 21:30:28 2001
*************** int main()
*** 19,29 ****
      // insert five random numbers
      generate_n (back_inserter(coll),      // beginning of destination range
                  5,                        // count
!                 rand);                    // new value generator
      PRINT_ELEMENTS(coll);
  
      // overwrite with five new random numbers
      generate (coll.begin(), coll.end(),   // destination range
!               rand);                      // new value generator
      PRINT_ELEMENTS(coll);
  }
--- 19,29 ----
      // insert five random numbers
      generate_n (back_inserter(coll),      // beginning of destination range
                  5,                        // count
!                 ::rand);                    // new value generator
      PRINT_ELEMENTS(coll);
  
      // overwrite with five new random numbers
      generate (coll.begin(), coll.end(),   // destination range
!               ::rand);                      // new value generator
      PRINT_ELEMENTS(coll);
  }
diff -cpr orig/cont/sortset.cpp neu/cont/sortset.cpp
*** orig/cont/sortset.cpp	Wed Dec 27 16:32:41 2000
--- neu/cont/sortset.cpp	Sat Mar 10 20:20:15 2001
*************** int main()
*** 19,27 ****
      /* create a string set
       * - initialized by all words from standard input
       */
!     set<string> coll((istream_iterator<string>(cin)),
!                      (istream_iterator<string>()));
! 
      // print all elements
      copy (coll.begin(), coll.end(),
            ostream_iterator<string>(cout, "\n"));
--- 20,27 ----
      /* create a string set
       * - initialized by all words from standard input
       */
!     set<string> coll((0,istream_iterator<string>(cin)),
!                      istream_iterator<string>());
      // print all elements
      copy (coll.begin(), coll.end(),
            ostream_iterator<string>(cout, "\n"));
diff -cpr orig/cont/sortvec.cpp neu/cont/sortvec.cpp
*** orig/cont/sortvec.cpp	Wed Dec 27 16:32:41 2000
--- neu/cont/sortvec.cpp	Sat Mar 10 20:20:50 2001
*************** int main()
*** 19,27 ****
      /* create a string vector
       * - initialized by all words from standard input
       */
!     vector<string> coll((istream_iterator<string>(cin)),
!                         (istream_iterator<string>()));
! 
      // sort elements
      sort (coll.begin(), coll.end());
  
--- 20,27 ----
      /* create a string vector
       * - initialized by all words from standard input
       */
!     vector<string> coll((0,istream_iterator<string>(cin)),
!                         istream_iterator<string>());
      // sort elements
      sort (coll.begin(), coll.end());
  
diff -cpr orig/fo/compose4.cpp neu/fo/compose4.cpp
*** orig/fo/compose4.cpp	Wed Dec 27 16:32:42 2000
--- neu/fo/compose4.cpp	Sat Mar 10 17:34:53 2001
*************** int main()
*** 24,36 ****
      // insert five random numbers
      generate_n (back_inserter(coll),      // beginning of destination range
                  5,                        // count
!                 rand);                    // new value generator
      PRINT_ELEMENTS(coll);
  
      // overwrite with five new random numbers
      // in the range between 0 (including) and 10 (excluding)
      generate (coll.begin(), coll.end(),   // destination range
                compose_f_g(bind2nd(modulus<int>(),10),
!                           ptr_fun(rand)));
      PRINT_ELEMENTS(coll);
  }
--- 24,36 ----
      // insert five random numbers
      generate_n (back_inserter(coll),      // beginning of destination range
                  5,                        // count
!                 ::rand);                    // new value generator
      PRINT_ELEMENTS(coll);
  
      // overwrite with five new random numbers
      // in the range between 0 (including) and 10 (excluding)
      generate (coll.begin(), coll.end(),   // destination range
                compose_f_g(bind2nd(modulus<int>(),10),
!                           ptr_fun(::rand)));
      PRINT_ELEMENTS(coll);
  }
diff -cpr orig/string/iter1.cpp neu/string/iter1.cpp
*** orig/string/iter1.cpp	Wed Dec 27 16:32:46 2000
--- neu/string/iter1.cpp	Sat Mar 10 17:36:34 2001
*************** int main()
*** 23,35 ****
      // lowercase all characters
      transform (s.begin(), s.end(),    // source
                 s.begin(),             // destination
!                tolower);              // operation
      cout << "lowered:  " << s << endl;
  
      // uppercase all characters
      transform (s.begin(), s.end(),    // source
                 s.begin(),             // destination
!                toupper);              // operation
      cout << "uppered:  " << s << endl;
  }
  
--- 23,35 ----
      // lowercase all characters
      transform (s.begin(), s.end(),    // source
                 s.begin(),             // destination
!                ::tolower);              // operation
      cout << "lowered:  " << s << endl;
  
      // uppercase all characters
      transform (s.begin(), s.end(),    // source
                 s.begin(),             // destination
!                ::toupper);              // operation
      cout << "uppered:  " << s << endl;
  }
  

The patch for sort{vec,int}.cpp is a known parser problem which is only
mendable by rewriting the parser, I have been told. 

But could someone please fix the other problem or make PR c++/3048 or 
PR c++/2295 a high priority bug report.

The problem in more detail:
extern "C" int rand (void) throw ();
namespace std
{ 
    extern "C" int rand(void) throw(); 
    template <class T> void f(T a) {}
}
     
using namespace std;
     
int main()
{
    f(rand);
    f(std::rand);
    f(::rand);
}
 
g++ -v tl.C -W -Wall
Reading specs from /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.0/specs
Configured with: ../gcc/configure --enable-shared --disable-nls --enable-threads=posix --enable-long-long --enable-languages=c,c++,f77,objc
Thread model: posix
gcc version 3.0 20010611 (prerelease)
 /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.0/cc1plus -v -D__GNUC__=3 -D__GNUC_MINOR__=0 -D__GNUC_PATCHLEVEL__=0 -D__ELF__ -Dunix -Dlinux -D__ELF__ -D__unix__ -D__linux__ -D__unix -D__linux -Asystem=posix -D__NO_INLINE__ -D__STDC_HOSTED__=1 -W -Wall -D_GNU_SOURCE -Acpu=i386 -Amachine=i386 -Di386 -D__i386 -D__i386__ -D__tune_i686__ -D__tune_pentiumpro__ tl.C -D__GNUG__=3 -D__GXX_DEPRECATED -D__EXCEPTIONS -D__GXX_ABI_VERSION=100 -quiet -dumpbase tl.C -W -Wall -version -o /tmp/cc2C2Yko.s
GNU CPP version 3.0 20010611 (prerelease) (cpplib) (i386 Linux/ELF)
GNU C++ version 3.0 20010611 (prerelease) (i686-pc-linux-gnu)
	compiled by GNU C version 3.0 20010611 (prerelease).
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include/g++-v3
 /usr/local/include/g++-v3/i686-pc-linux-gnu
 /usr/local/include/g++-v3/backward
 /usr/local/include
 /usr/local/lib/gcc-lib/i686-pc-linux-gnu/3.0/include
 /usr/local/i686-pc-linux-gnu/include
 /usr/include
End of search list.
tl.C: In function `int main()':
tl.C:12: no matching function for call to `f(<unknown type>)'
tl.C: In function `void std::f(T) [with T = int (*)() throw ()]':
tl.C:13:   instantiated from here
tl.C:5: warning: unused parameter `int (*a)() throw ()'


After applying both patches I can compile all example programs (g++  -W
-Wall -pedantic -O3) without a warning but not all executables run fine: 

There are some remaining problems because of missing or not full
fledged functionality of the the current libstdc++ library.

All executables of the i18n directory do not work as expected because
of only preliminary support for named locales. The posix (C) locale is
hard coded. Therefore, the results of loc1 and loc2 of the i18n
directory are comprehensible. But numget does not work at all; I
believe this is a problem with use_facet<std::num_get<char, InIt> >(loc). 

Additionally, there is another problem with the execution of
num/complex2.C. The tieing of the input and the output stream seems not to
work. Please confer PR libstdc++/943 .

Could you please fix PR libstdc++/943 and PR c++/3048 before the gcc 3.0
compiler is released.

Thanks in advance,

Peter Schmid



More information about the Libstdc++ mailing list