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