Question

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?

Was it helpful?

Solution

*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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top