Boost
C++ Libraries
...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
![]() |
Home | Libraries | People | FAQ | More |
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.
_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, which is 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 (up to SP4) | 1200 |
using-declarationsusing-declarations does not work.
void f();
namespace N {
using ::f;
}
void g()
{
using N::f; // C2873: 'f': the symbol cannot be used in a using-declaration
}
#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 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.
Another possible workaround (brought to my attention by Vesa Karvonen) is this:
#ifndef for
#define for if (0) {} else for
#endif
Note that platform-specific inline functions in included headers might
depend on the old-style for scoping.
std::numeric_limits template, does
not work.
struct A
{
static const int i = 5; // "invalid syntax for pure virtual method"
};
Workaround: 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
using the constant in compile-time constant expressions). See
Coding Guidelines for Integral Constant Expressions
for guidelines how to define member constants portably in boost
libraries.
namespace N {
struct A {};
void f(A);
}
void g()
{
N::A a;
f(a); // 'f': undeclared identifier
}
template<class T>
struct A {};
struct B
{
template<class T>
friend struct A; // "syntax error"
};
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.
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, class member templates can simulate partial
specialization.
template<class T, typename T::result_type> // C1001: INTERNAL COMPILER ERROR: msc1.cpp, line 1794
struct B {};
// (omit "typename" and it compiles)
Workaround: Leave off the "typename" keyword. That makes
the program non-conforming, though.
wchar_t is not built-inwchar_t is not a built-in type.
wchar_t x; // "missing storage class or type identifier"Workaround: When using Microsoft Visual C++, the header boost/config.hpp includes
<cstddef>, which defines
wchar_t as a typedef for unsigned
short. Note that this means that the compiler does not regard
wchar_t and unsigned short as distinct
types, as is required by the standard, and so ambiguities may emanate
when overloading on wchar_t. The macro
BOOST_NO_INTRINSIC_WCHAR_T is defined in this situation.
const X * does not work
void f()
{
const int *p = new int(5);
delete p; // C2664: cannot convert from "const int *" to "void *"
}
Workaround: Define the function
inline void operator delete(const void *p) throw()
{ operator delete(const_cast<void*>(p)); }
and similar functions for the other cv-qualifier combinations, for
operator delete[], and for the std::nothrow variants.
Library names from the <c...> headers are in the global namespace instead of namespace std.
Workaround: The header boost/config.hpp will define BOOST_NO_STDC_NAMESPACE. It can be used as follows:
# ifdef BOOST_NO_STDC_NAMESPACE
namespace std { using ::abs; using ::fabs; }
# endif
Because std::size_t and std::ptrdiff_t are so commonly used, the workaround for these is already provided in boost/config.hpp.