When analyzing some Boost dependent code through the Clang static analyzer, I got the following error:
Logic error Called C++ object pointer is null usage.hpp 22
from the following code in boost/concept/usage.hpp
template <class Model>
struct usage_requirements
{
~usage_requirements() { ((Model*)0)->~Model(); }
};
Question: is this a real bug in Boost or does Boost.Concept call a destructor through a null pointer to somehow generate compiler errors during concept checking?
*Disclaimer. Take this with some salt, I am in no way a Boost Concept expert.
It used in order to make the compiler to instantiate the "Model" destructor to make the compiler generate errors for concept failures.
usage_requirements
is used together with BOOST_CONCEPT_USAGE
which is used while creating new concepts, see Creating Concepts in the documentation.
# define BOOST_CONCEPT_USAGE(model) \
model(); /* at least 2.96 and 3.4.3 both need this :( */ \
BOOST_CONCEPT_ASSERT((boost::concepts::usage_requirements<model>)); \
~model()
Which is used like:
BOOST_CONCEPT_USAGE(InputIterator)
{
X j(i); // require copy construction
same_type(*i++,v); // require postincrement-dereference returning value_type
X& x = ++j; // require preincrement returning X&
}
Which will end up like:
model(); /* at least 2.96 and 3.4.3 both need this :( */ \
BOOST_CONCEPT_ASSERT((boost::concepts::usage_requirements<model>)); \
~model()
{
X j(i); // require copy construction
same_type(*i++,v); // require postincrement-dereference returning value_type
X& x = ++j; // require preincrement returning X&
}
As you can see, the concept requirements end up in the model
destructor. Which is why we need to fool the compiler to instantiate it.