No C++ compiler is perfect. Each may have its strengths and weaknesses. The real problems occur when a code needs to be portable. Lowering the code to the least common denominator is ugly and frustrating. Frequently it results with runtime inefficiency also in versions compiled by well behaved ANSI complying compilers.
Following are some annoying examples of perfectly standard C++ code that Visual C++ 6.0 is simply too stupid to handle. Needless to say that all are nicely compiled by g++. If you encounter other Visual C++ compiler bugs, please reduce them to less than 25 lines and send me for credited publication here. For g++ bugs you may simply see an honest listing. You are encouraged to report new discovered g++ bugs which are archived. Hey, If you are smart enough and have a good will, fix it and send a patch!
The standard defines that the scope of defined variable in a for-loop statement ends with the end of the for-block. Thus the following code is legal. But...
forfor.cppvoid forfor(int n, int& add, int& mult) {
for (int i = 1; i < n; ++i) add += i;
for (int i = 1; i < n; ++i) mult *= i;
}
For which we get: H:\C\MSVC6\dos>cl /c forfor.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.
forfor.cpp
forfor.cpp(3) : error C2374: 'i' : redefinition; multiple initialization
forfor.cpp(2) : see declaration of 'i'
Now look at the following forofor.cpp code which is actually illegal and how nicely g++ treats it
celini:45> cat forofor.cpp; g++ -c -Wall forofor.cpp
void forfor(int n, int& add, int& mult) {
for (int i = 1; i < n; ++i) add += i;
for (i = 1; i < n; ++i) mult *= i;
}
forofor.cpp: In function void forfor(int, int &, int &):
forofor.cpp:3: name lookup of i changed for new ANSI for scoping
forofor.cpp:2: using obsolete binding at i
class C {
public:
C() {}
virtual ~C() {}
virtual C* clone() const = 0;
}; // C
class B : public C {
public:
B(int i = 0) : n(i) {}
virtual ~B() {}
B* clone() const {return new B(*this);}
int n;
}; // B
For which we get: H:\C\MSVC6\dos>cl /c covar.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.
covar.cpp
covar.cpp(12) : error C2555: 'B::clone' : overriding virtual function differs from 'C::clone' only by return type or calling convention
covar.cpp(1) : see declaration of 'C'
#include <algorithm>
#include <vector>
class C {
public:
class I {
public:
I(int i = 0) : _n(i) {}
int _n;
}; // I
}; // C
bool operator==(const C::I& b0, const C::I& b1) {
return b0._n == b1._n;
}
int iFind(const std::vector<C::I>& vi, const C::I& i) {
std::vector<C::I>::const_iterator where =
std::find(vi.begin(), vi.end(), i);
return (where != vi.end() ? where - vi.begin() : -1);
} // iFind
For which we get: H:\C\MSVC6\dos>cl /c /GX nest.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.
nest.cpp
D:\Apps\VS6\VC98\INCLUDE\algorithm(43) : error C2784: 'bool __cdecl std::operator ==(const class std::vector<_Ty,_A> &,const class std::vector<_Ty,_A> &)' : could not deduce template argument for 'const class std::vector<_Ty,_A> &' from 'const class C::I'
nest.cpp(20) : see reference to function template instantiation 'const class C::I *__cdecl std::find(const class C::I *,const class C::I *,const class C::I &)' being compiled
D:\Apps\VS6\VC98\INCLUDE\algorithm(43) : error C2784: 'bool __cdecl std::operator ==(const class std::allocator<_Ty> &,const class std::allocator<_U> &)' : could not deduce template argument for 'const class std::allocator<_Ty> &' from 'const class C::I'
nest.cpp(20) : see reference to function template instantiation 'const class C::I *__cdecl std::find(const class C::I *,const class C::I *,const class C::I &)' being compiled
D:\Apps\VS6\VC98\INCLUDE\algorithm(43) : error C2784: 'bool __cdecl std::operator ==(const class std::istream_iterator<_U,_E,_Tr> &,const class std::istream_iterator<_U,_E,_Tr> &)' : could not deduce template argument for 'const class std::istream_iterator<_U,_E,_Tr> &' from 'const class C::I'
nest.cpp(20) : see reference to function template instantiation 'const class C::I *__cdecl std::find(const class C::I *,const class C::I *,const class C::I &)' being compiled
D:\Apps\VS6\VC98\INCLUDE\algorithm(43) : error C2784: 'bool __cdecl std::operator ==(const class std::reverse_bidirectional_iterator<_BI,_Ty,_Rt,_Pt,_D> &,const class std::reverse_bidirectional_iterator<_BI,_Ty,_Rt,_Pt,_D> &)' : could not deduce template argument for 'const class std::reverse_bidirectional_iterator<_BI,_Ty,_Rt,_Pt,_D> &' from 'const class C::I'
nest.cpp(20) : see reference to function template instantiation 'const class C::I *__cdecl std::find(const class C::I *,const class C::I *,const class C::I &)' being compiled
D:\Apps\VS6\VC98\INCLUDE\algorithm(43) : error C2784: 'bool __cdecl std::operator ==(const class std::istreambuf_iterator<_E,_Tr> &,const class std::istreambuf_iterator<_E,_Tr> &)' : could not deduce template argument for 'const class std::istreambuf_iterator<_E,_Tr> &' from 'const class C::I'
nest.cpp(20) : see reference to function template instantiation 'const class C::I *__cdecl std::find(const class C::I *,const class C::I *,const class C::I &)' being compiled
D:\Apps\VS6\VC98\INCLUDE\algorithm(43) : error C2784: 'bool __cdecl std::operator ==(const class std::reverse_iterator<_RI,_Ty,_Rt,_Pt,_D> &,const class std::reverse_iterator<_RI,_Ty,_Rt,_Pt,_D> &)' : could not deduce template argument for 'const class std::reverse_iterator<_RI,_Ty,_Rt,_Pt,_D> &' from 'const class C::I'
nest.cpp(20) : see reference to function template instantiation 'const class C::I *__cdecl std::find(const class C::I *,const class C::I *,const class C::I &)' being compiled
D:\Apps\VS6\VC98\INCLUDE\algorithm(43) : error C2784: 'bool __cdecl std::operator ==(const struct std::pair<_T1,_T2> &,const struct std::pair<_T1,_T2> &)' : could not deduce template argument for 'const struct std::pair<_T1,_T2> &' from 'const class C::I'
nest.cpp(20) : see reference to function template instantiation 'const class C::I *__cdecl std::find(const class C::I *,const class C::I *,const class C::I &)' being compiled
D:\Apps\VS6\VC98\INCLUDE\algorithm(43) : error C2676: binary '==' : 'const class C::I' does not define this operator or a conversion to a type acceptable to the predefined operator
nest.cpp(20) : see reference to function template instantiation 'const class C::I *__cdecl std::find(const class C::I *,const class C::I *,const class C::I &)' being compiled
#include <iostream.h>
class P {
public:
P() { cout << "P::P" << endl; }
}; // P
void fun4P(P*) { cout << "fun4P" << endl; }
template<class T, void (*funT)(T*)>
class TC
{
public:
TC() : _pT(new T) {}
~TC() {fun4P(_pT);}
private:
T* _pT;
};
int main(int, char**) {
typedef TC<P, &fun4P> ProblemIsHereCls;
ProblemIsHereCls Problem;
return 0;
}
For which we get: H:\C\MSVC6\dos>cl /c funtempl.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.
funtempl.cpp
funtempl.cpp(21) : error C2440: 'specialization' : cannot convert from 'void (__cdecl *)(class P *)' to 'void (__cdecl *)( *)'
This conversion requires a reinterpret_cast, a C-style cast or function-style cast
funtempl.cpp(21) : error C2975: 'TC' : invalid template argument for 'funT', constant expression expected
funtempl.cpp(18) : see declaration of 'TC'
funtempl.cpp(22) : error C2079: 'Problem' uses undefined class 'TC'
template <class T>
struct A {
typename T::DT i;
};
#if !defined(DoNotConfuseMSVisual)
template <class T>
typename T::DT foo(const A<T> &a);
#endif
template <class T>
typename T::DT foo(const A<T> &a) {
return a.i+a.i;
};
struct DTdef {
typedef long DT;
};
int main() {
A<DTdef> a;
a.i=7;
return foo(a)-14;
}
For which we get: H:\C\MSVC6\dos>cl /c fordecdt.cpp Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86 Copyright (C) Microsoft Corp 1984-1998. All rights reserved. fordecdt.cpp fordecdt.cpp(23) : error C2667: 'foo' : none of 2 overload have a best conversion fordecdt.cpp(23) : error C2668: 'foo' : ambiguous call to overloaded function fordecdt.cpp(23) : warning C4508: 'main' : function should return a value; 'void' return type assumedOnly by suppressing the forward declaration via -DDoNotConfuseMSVisual that Visual-C++ can compile this:
H:\C\MSVC6\dos>cl /c /DDoNotConfuseMSVisual fordecdt.cpp Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86 Copyright (C) Microsoft Corp 1984-1998. All rights reserved. fordecdt.cpp
// example3.C - compile with cl -TP -c example3.C
#include <list>
template <class P> class blah {
void bbb(std::list<P> &l);
};
template <int D> class B1
{
private:
double v[ D ];
};
typedef B1<4> pt;
For which we get: H:\C\MSVC6\dos>cl /c fatc1001.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.
fatc1001.cpp
fatc1001.cpp(6) : fatal error C1001: INTERNAL COMPILER ERROR
(compiler file 'msc1.cpp', line 1786)
Please choose the Technical Support command on the Visual C++
Help menu, or open the Technical Support help file for more information
f();
enum {f};
For which we get: H:\C\MSVC6\dos>cl /c fenum.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.
fenum.cpp
fenum.cpp(2) : fatal error C1001: INTERNAL COMPILER ERROR
(compiler file 'msc1.cpp', line 1794)
Please choose the Technical Support command on the Visual C++
Help menu, or open the Technical Support help file for more information
The g++ gives:
fenum.cpp:1: ANSI C++ forbids declaration f with no type
fenum.cpp:2: enum {anonymous} f redeclared as different kind of symbol
fenum.cpp:1: previous declaration of int f()
// Similar to "C++ Programming Language" Special Edition (2000) / Stoustrup
// 14.4.6.1. Exceptions and member Initialization (p. 373)
class X {
int val;
public:
X()
try
: val(0)
{}
catch (...)
{}
};
This is successfully compiled by g++
but Visual C++ gives: Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.
excptini.cpp
excptini.cpp(6) : error C2143: syntax error : missing ';' before 'try'
excptini.cpp(6) : error C2059: syntax error : 'try'
excptini.cpp(6) : error C2334: unexpected token(s) preceding ':'; skipping apparent function body
excptini.cpp(10) : error C2059: syntax error : 'catch'
excptini.cpp(11) : error C2334: unexpected token(s) preceding '{'; skipping apparent function body
// Similar to "C++ Programming Language" Special Edition (2000) / Stoustrup
// 14.4.6.1. Exceptions and member Initialization (p. 373)
class X {
public:
int method()
try {
return 0;
}
catch (...) {
return 0;
}
};
This is successfully compiled by g++
but Visual C++ gives: H:\C\MSVC6\dos>cl /c excptini.cpp
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8168 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.
excptini.cpp
excptmth.cpp(6) : error C2143: syntax error : missing ';' before 'try'
excptmth.cpp(6) : error C2059: syntax error : 'try'
excptmth.cpp(6) : error C2334: unexpected token(s) preceding '{'; skipping apparent function body
excptmth.cpp(9) : error C2059: syntax error : 'catch'
excptmth.cpp(9) : error C2334: unexpected token(s) preceding '{'; skipping apparent function body
Back to my Software Page.
This page received
hits.