2001-02-02 06:28:23 +08:00
|
|
|
<html>
|
|
|
|
<head>
|
|
|
|
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
|
|
|
|
<title>Portability Hints: Microsoft Visual C++ 6.0 SP4</title>
|
|
|
|
</head>
|
|
|
|
|
|
|
|
<body bgcolor="#FFFFFF" text="#000000">
|
|
|
|
|
|
|
|
<table border="1" bgcolor="#007F7F" cellpadding="2">
|
|
|
|
<tr>
|
|
|
|
<td bgcolor="#FFFFFF"><img src="../c++boost.gif" alt="c++boost.gif (8819 bytes)" width="277" height="86"></td>
|
|
|
|
<td><a href="../index.htm"><font face="Arial,Helvetica" color="#FFFFFF"><big>Home</big></font></a></td>
|
|
|
|
<td><a href="../libs/libraries.htm"><font face="Arial,Helvetica" color="#FFFFFF"><big>Libraries</big></font></a></td>
|
|
|
|
<td><a href="../people/people.htm"><font face="Arial,Helvetica" color="#FFFFFF"><big>People</big></font></a></td>
|
|
|
|
<td><a href="faq.htm"><font face="Arial,Helvetica" color="#FFFFFF"><big>FAQ</big></font></a></td>
|
|
|
|
<td><a href="index.htm"><font face="Arial,Helvetica" color="#FFFFFF"><big>More</big></font></a></td>
|
|
|
|
</tr>
|
|
|
|
</table>
|
|
|
|
|
|
|
|
<p>
|
|
|
|
|
|
|
|
<h1>Portability Hints: Microsoft Visual C++ 6.0 SP4</h1>
|
|
|
|
|
|
|
|
Similar to the
|
|
|
|
<a href="borland_cpp.html">portability hints for Borland C++</a>,
|
|
|
|
this page provides hints on some language features of the Microsoft Visual C++
|
2001-02-03 06:23:04 +08:00
|
|
|
version 6.0 service pack 4 compiler. A list of
|
|
|
|
acknowledged deficiencies can be found at the
|
|
|
|
<a href="http://support.microsoft.com/support/kb/articles/q243/4/51.asp">Microsoft support site</a>.
|
|
|
|
<p>
|
2001-02-02 06:28:23 +08:00
|
|
|
|
|
|
|
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.
|
|
|
|
|
|
|
|
|
|
|
|
<h2>Preprocessor symbol</h2>
|
|
|
|
|
|
|
|
The preprocessor symbol <code>_MSC_VER</code> 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
|
2001-02-05 00:27:05 +08:00
|
|
|
<code>BOOST_MSVC</code>, which is defined in
|
2001-02-02 06:28:23 +08:00
|
|
|
<a href="../boost/config.hpp">boost/config.hpp</a>
|
|
|
|
to the value of _MSC_VER if and only if the compiler is really
|
|
|
|
Microsoft Visual C++.
|
|
|
|
|
|
|
|
The following table lists some known values.
|
|
|
|
<p>
|
|
|
|
|
|
|
|
<table border="1">
|
|
|
|
<tr>
|
|
|
|
<th>Compiler</th>
|
|
|
|
<th><code>BOOST_MSVC</code> value</th>
|
|
|
|
</tr>
|
|
|
|
|
|
|
|
<tr>
|
2001-02-13 03:13:41 +08:00
|
|
|
<td>Microsoft Visual C++ 6.0 (up to SP4)</td>
|
2001-02-02 06:28:23 +08:00
|
|
|
<td>1200</td>
|
|
|
|
</tr>
|
|
|
|
|
|
|
|
</table>
|
|
|
|
|
|
|
|
|
|
|
|
<h2>Core Language</h2>
|
|
|
|
|
|
|
|
<h3>[chained using] Chaining <code>using</code>-declarations</h3>
|
|
|
|
|
2001-05-06 04:25:25 +08:00
|
|
|
Chaining <code>using</code>-declarations does not work.
|
2001-02-02 06:28:23 +08:00
|
|
|
<pre>
|
|
|
|
void f();
|
|
|
|
|
|
|
|
namespace N {
|
|
|
|
using ::f;
|
|
|
|
}
|
|
|
|
|
|
|
|
void g()
|
|
|
|
{
|
|
|
|
using N::f; // C2873: 'f': the symbol cannot be used in a using-declaration
|
|
|
|
}
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
|
|
<h3>[explicit-instantiation] Explicit function template
|
|
|
|
instantiation</h3>
|
|
|
|
|
|
|
|
Trying to explicitly instantiate a function template leads to the
|
|
|
|
wrong function being called silently.
|
|
|
|
|
|
|
|
<pre>
|
2001-02-02 09:59:51 +08:00
|
|
|
#include <stdio.h>
|
2001-02-02 06:28:23 +08:00
|
|
|
|
2001-02-02 09:59:51 +08:00
|
|
|
template<class T>
|
2001-02-02 06:28:23 +08:00
|
|
|
void f()
|
|
|
|
{
|
2001-02-02 09:59:51 +08:00
|
|
|
printf("%d\n", sizeof(T));
|
2001-02-02 06:28:23 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
int main()
|
|
|
|
{
|
2001-02-02 09:59:51 +08:00
|
|
|
f<double>(); // output: "1"
|
|
|
|
f<char>(); // output: "1"
|
2001-02-02 06:28:23 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
|
|
<h3>[for-scoping] Scopes of definitions in for-loops</h3>
|
|
|
|
|
|
|
|
The scope of variable definitions in <code>for</code> loops should be
|
|
|
|
local to the loop's body, but it is instead local to the enclosing
|
2001-02-03 06:16:23 +08:00
|
|
|
block.
|
2001-02-02 06:28:23 +08:00
|
|
|
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
int main()
|
|
|
|
{
|
|
|
|
for(int i = 0; i < 5; ++i)
|
|
|
|
;
|
|
|
|
for(int i = 0; i < 5; ++i) // C2374: 'i': Redefinition; multiple initialization
|
|
|
|
;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
<strong>Workaround:</strong> Enclose the offending <code>for</code>
|
|
|
|
loops in another pair of curly braces.
|
2002-01-21 02:13:40 +08:00
|
|
|
<p>
|
|
|
|
Another possible workaround (brought to my attention by Vesa Karvonen)
|
|
|
|
is this:
|
|
|
|
<pre>
|
|
|
|
#ifndef for
|
|
|
|
#define for if (0) {} else for
|
|
|
|
#endif
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
Note that platform-specific inline functions in included headers might
|
|
|
|
depend on the old-style <code>for</code> scoping.
|
2001-02-02 06:28:23 +08:00
|
|
|
|
|
|
|
|
|
|
|
<h3>[inclass-member-init] In-class member initialization</h3>
|
|
|
|
|
2001-02-12 03:34:33 +08:00
|
|
|
In-class member initialization, required to implement a
|
2001-02-02 06:28:23 +08:00
|
|
|
Standard-conforming <code>std::numeric_limits</code> template, does
|
|
|
|
not work.
|
|
|
|
|
|
|
|
<pre>
|
|
|
|
struct A
|
|
|
|
{
|
2001-02-02 09:59:51 +08:00
|
|
|
static const int i = 5; // "invalid syntax for pure virtual method"
|
2001-02-02 06:28:23 +08:00
|
|
|
};
|
|
|
|
</pre>
|
|
|
|
|
2001-02-12 03:34:33 +08:00
|
|
|
<strong>Workaround:</strong> Either use an enum (which has incorrect
|
|
|
|
type, but can be used in compile-time constant expressions), or define
|
|
|
|
the value out-of-line (which allows for the correct type, but prohibits
|
2001-05-06 04:25:25 +08:00
|
|
|
using the constant in compile-time constant expressions). See
|
|
|
|
<a href="int_const_guidelines.htm">Coding Guidelines for Integral Constant Expressions</a>
|
|
|
|
for guidelines how to define member constants portably in boost
|
|
|
|
libraries.
|
|
|
|
|
2001-02-02 06:28:23 +08:00
|
|
|
|
|
|
|
<h3>[koenig-lookup] Argument-dependent lookup</h3>
|
|
|
|
|
2001-02-13 03:13:41 +08:00
|
|
|
Argument-dependent lookup, also called Koenig lookup, works for
|
|
|
|
overloaded operators, but not for ordinary functions. No
|
|
|
|
additional namespaces induced from the argument types seem to be
|
|
|
|
considered.
|
2001-02-02 06:28:23 +08:00
|
|
|
|
|
|
|
<pre>
|
|
|
|
namespace N {
|
|
|
|
struct A {};
|
|
|
|
void f(A);
|
|
|
|
}
|
|
|
|
|
|
|
|
void g()
|
|
|
|
{
|
|
|
|
N::A a;
|
|
|
|
f(a); // 'f': undeclared identifier
|
|
|
|
}
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
|
|
<h3>[template-friend] Templates as friends</h3>
|
|
|
|
|
|
|
|
A Template cannot be declared a friend of a class.
|
|
|
|
|
|
|
|
<pre>
|
2001-02-02 09:59:51 +08:00
|
|
|
template<class T>
|
2001-02-02 06:28:23 +08:00
|
|
|
struct A {};
|
|
|
|
|
|
|
|
struct B
|
|
|
|
{
|
2001-02-02 09:59:51 +08:00
|
|
|
template<class T>
|
|
|
|
friend struct A; // "syntax error"
|
2001-02-02 06:28:23 +08:00
|
|
|
};
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
|
|
|
|
<h3>[member-template-outofline] Out-of-line definitions of member
|
|
|
|
templates</h3>
|
|
|
|
|
|
|
|
Defining member templates outside their enclosing class does not work.
|
|
|
|
|
|
|
|
<pre>
|
2001-02-02 09:59:51 +08:00
|
|
|
template<class T>
|
2001-02-02 06:28:23 +08:00
|
|
|
struct A
|
|
|
|
{
|
2001-02-02 09:59:51 +08:00
|
|
|
template<class U>
|
2001-02-02 06:28:23 +08:00
|
|
|
void f();
|
|
|
|
};
|
|
|
|
|
2001-02-02 09:59:51 +08:00
|
|
|
template<class T>
|
|
|
|
template<class U> // "syntax error"
|
|
|
|
void A<T>::f() // "T: undeclared identifier"
|
2001-02-02 06:28:23 +08:00
|
|
|
{
|
|
|
|
}
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
<strong>Workaround:</strong> Define member templates in-line within
|
|
|
|
their enclosing class.
|
|
|
|
|
|
|
|
|
|
|
|
<h3>[partial-spec] Partial specialization</h3>
|
|
|
|
|
|
|
|
Partial specialization of class templates does not work.
|
|
|
|
|
|
|
|
<pre>
|
2001-02-02 09:59:51 +08:00
|
|
|
template<class T>
|
2001-02-02 06:28:23 +08:00
|
|
|
struct A {};
|
|
|
|
|
2001-02-02 09:59:51 +08:00
|
|
|
template<class T>
|
2001-02-02 06:28:23 +08:00
|
|
|
struct B {};
|
|
|
|
|
2001-02-02 09:59:51 +08:00
|
|
|
template<class T>
|
|
|
|
struct A<B<T> > {}; // template class was already defined as a non-template
|
2001-02-02 06:28:23 +08:00
|
|
|
</pre>
|
|
|
|
|
|
|
|
<strong>Workaround:</strong> In some situations where interface
|
2001-05-06 04:25:25 +08:00
|
|
|
does not matter, class member templates can simulate partial
|
2001-02-02 06:28:23 +08:00
|
|
|
specialization.
|
|
|
|
|
|
|
|
|
2001-02-02 09:59:51 +08:00
|
|
|
<h3>[template-value] Dependent template value parameters</h3>
|
2001-02-02 06:28:23 +08:00
|
|
|
|
|
|
|
Template value parameters whose type depends on a previous template
|
|
|
|
parameter provoke an internal compiler error if the correct syntax
|
|
|
|
(with "typename") is used.
|
|
|
|
|
|
|
|
<pre>
|
2001-02-03 03:58:57 +08:00
|
|
|
template<class T, typename T::result_type> // C1001: INTERNAL COMPILER ERROR: msc1.cpp, line 1794
|
2001-02-02 06:28:23 +08:00
|
|
|
struct B {};
|
2001-02-02 09:59:51 +08:00
|
|
|
// (omit "typename" and it compiles)
|
2001-02-02 06:28:23 +08:00
|
|
|
|
|
|
|
</pre>
|
|
|
|
|
2001-02-12 03:34:33 +08:00
|
|
|
<strong>Workaround:</strong> Leave off the "typename" keyword. That makes
|
|
|
|
the program non-conforming, though.
|
|
|
|
|
2001-02-02 06:28:23 +08:00
|
|
|
|
|
|
|
<h3>[wchar_t] <code>wchar_t</code> is not built-in</h3>
|
|
|
|
|
|
|
|
The type <code>wchar_t</code> is not a built-in type.
|
|
|
|
|
|
|
|
<pre>
|
2001-02-02 09:59:51 +08:00
|
|
|
wchar_t x; // "missing storage class or type identifier"
|
2001-02-02 06:28:23 +08:00
|
|
|
</pre>
|
|
|
|
|
2001-02-05 00:27:05 +08:00
|
|
|
<strong>Workaround:</strong> When using Microsoft Visual C++, the
|
|
|
|
header
|
2001-02-03 06:16:23 +08:00
|
|
|
<a href="../boost/config.hpp">boost/config.hpp</a>
|
2001-02-12 03:34:33 +08:00
|
|
|
includes <code><cstddef></code>, which defines
|
2001-02-05 00:27:05 +08:00
|
|
|
<code>wchar_t</code> as a typedef for <code>unsigned
|
2001-05-06 04:25:25 +08:00
|
|
|
short</code>. Note that this means that the compiler does not regard
|
2001-02-05 00:27:05 +08:00
|
|
|
<code>wchar_t</code> and <code>unsigned short</code> as distinct
|
|
|
|
types, as is required by the standard, and so ambiguities may emanate
|
2001-02-05 00:35:09 +08:00
|
|
|
when overloading on <code>wchar_t</code>. The macro
|
|
|
|
<code>BOOST_NO_INTRINSIC_WCHAR_T</code> is defined in this situation.
|
2001-02-02 06:28:23 +08:00
|
|
|
|
2001-05-10 01:38:30 +08:00
|
|
|
|
|
|
|
<h3>[delete-const-pointer] Deleting <code>const X *</code> does not work</h3>
|
|
|
|
|
|
|
|
Trying to delete a pointer to a cv-qualified type gives an error:
|
|
|
|
<pre>
|
|
|
|
void f()
|
|
|
|
{
|
|
|
|
const int *p = new int(5);
|
|
|
|
delete p; // C2664: cannot convert from "const int *" to "void *"
|
|
|
|
}
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
<strong>Workaround:</strong> Define the function
|
|
|
|
<pre>
|
|
|
|
inline void operator delete(const void *p) throw()
|
|
|
|
{ operator delete(const_cast<void*>(p)); }
|
|
|
|
</pre>
|
|
|
|
and similar functions for the other cv-qualifier combinations, for
|
|
|
|
operator delete[], and for the <code>std::nothrow</code> variants.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<h2>Standard Library</h2>
|
|
|
|
|
2001-02-02 09:59:51 +08:00
|
|
|
<h3>[clib-namespace] C library names in global namespace instead of std</h3>
|
|
|
|
<p>Library names from the <c...> headers are in the global namespace
|
2001-09-19 05:24:51 +08:00
|
|
|
instead of namespace std.<p><b>Workaround:</b> The header <a href="../libs/config/config.htm">boost/config.hpp</a>
|
2001-02-02 09:59:51 +08:00
|
|
|
will define BOOST_NO_STDC_NAMESPACE. It can be used as follows:
|
|
|
|
<pre># ifdef BOOST_NO_STDC_NAMESPACE
|
|
|
|
namespace std { using ::abs; using ::fabs; }
|
|
|
|
# endif</pre>
|
|
|
|
<p>Because std::size_t and std::ptrdiff_t are so commonly used, the workaround
|
|
|
|
for these is already provided in boost/config.hpp.<p>
|
2001-02-02 06:28:23 +08:00
|
|
|
<hr>
|
|
|
|
|
2001-05-06 04:25:25 +08:00
|
|
|
2001-05-04 <a href="../people/jens_maurer.htm">Jens Maurer</a>
|
2001-02-02 06:28:23 +08:00
|
|
|
</body>
|
|
|
|
</html>
|