MicroSoft Visual C++ Deficiencies

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!

Contents:


Scope of for Variable

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.cpp
void 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

Covariant Return Type

covar.cpp
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'


Template of Nested Class

nest.cpp
#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

Function Template Parameter

funtempl.cpp (sent by Michael Tsirkin)
#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'


Confused by Template Forward Declaration

fordecdt.cpp (sent by Dmitrii Pasechnik)
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 assumed


Only 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


Fatal Compiler Error

fatc1001.cpp (sent by Dmitrii Pasechnik)
// 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

Internal Compiler Error

fenum.cpp (sent by Ionut Filip)
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()

A try/catch block in initialization

excptini.cpp (sent by Ionut Filip)
// 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

A try/catch block in method

excptmth.cpp (sent by Ionut Filip)
// 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.