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; }; // BFor 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); } // iFindFor 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 informationThe 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.