Portability Hints: Microsoft Visual C++ 6.0 SP4
Similar to the
portability hints for Borland C++,
this page provides hints on some language features of the Microsoft Visual C++
version 6.0 servicepack 4 compiler.
Each entry in the following list describes a particular issue,
complete with sample source code to demonstrate the effect.
Most sample code herein has been verified to compile with gcc 2.95.2
and Comeau C++ 4.2.44.
Preprocessor symbol
The preprocessor symbol _MSC_VER is defined for all
Microsoft C++ compilers. Its value is the internal version number of the
compiler interpreted as a decimal number. Since a few other compilers
also define this symbol, boost provides the symbol
BOOST_MSVC defined in
boost/config.hpp
to the value of _MSC_VER if and only if the compiler is really
Microsoft Visual C++.
The following table lists some known values.
| Compiler |
BOOST_MSVC value |
| Microsoft Visual C++ 6.0 SP4 |
1200 |
Core Language
[chained using] Chaining using-declarations
Chaining using-declarations do not work.
void f();
namespace N {
using ::f;
}
void g()
{
using N::f; // C2873: 'f': the symbol cannot be used in a using-declaration
}
[explicit-instantiation] Explicit function template
instantiation
Trying to explicitly instantiate a function template leads to the
wrong function being called silently.
#include <stdio.h>
template<class T>
void f()
{
printf("%d\n", sizeof(T));
}
int main()
{
f<double>(); // output: "1"
f<char>(); // output: "1"
return 0;
}
[for-scoping] Scopes of definitions in for-loops
The scope of variable definitions in for loops should be
local to the loop's body, but it is instead local to the enclosing
block:
int main()
{
for(int i = 0; i < 5; ++i)
;
for(int i = 0; i < 5; ++i) // C2374: 'i': Redefinition; multiple initialization
;
return 0;
}
Workaround: Enclose the offending for
loops in another pair of curly braces.
[inclass-member-init] In-class member initialization
In-class member initialization, require to implement a
Standard-conforming std::numeric_limits template, does
not work.
struct A
{
static const int i = 5; // "invalid syntax for pure virtual method"
};
[koenig-lookup] Argument-dependent lookup
Argument-dependent lookup, also called Koenig lookup, does not work.
No additional namespace induced from the argument types seem to be
considered.
namespace N {
struct A {};
void f(A);
}
void g()
{
N::A a;
f(a); // 'f': undeclared identifier
}
[template-friend] Templates as friends
A Template cannot be declared a friend of a class.
template<class T>
struct A {};
struct B
{
template<class T>
friend struct A; // "syntax error"
};
[member-template-outofline] Out-of-line definitions of member
templates
Defining member templates outside their enclosing class does not work.
template<class T>
struct A
{
template<class U>
void f();
};
template<class T>
template<class U> // "syntax error"
void A<T>::f() // "T: undeclared identifier"
{
}
Workaround: Define member templates in-line within
their enclosing class.
[partial-spec] Partial specialization
Partial specialization of class templates does not work.
template<class T>
struct A {};
template<class T>
struct B {};
template<class T>
struct A<B<T> > {}; // template class was already defined as a non-template
Workaround: In some situations where interface
does not matter, member class templates can simulate partial
specialization.
[template-value] Dependent emplate value parameters
Template value parameters whose type depends on a previous template
parameter provoke an internal compiler error if the correct syntax
(with "typename") is used.
template<class T, typename T::result_type> // C1001: INTERNAL COMPILER ERROR: ms
c1.cpp, line 1794
struct B {};
// (omit "typename" and it compiles)
[wchar_t] wchar_t is not built-in
The type wchar_t is not a built-in type.
wchar_t x; // "missing storage class or type identifier"
2001-02-01 Jens Maurer