bug: cyclic header dependencies in type_traits

In Boost 1.33.1, the following headers are involved in an #inclusion cycle: boost/type_traits/is_scalar.hpp boost/type_traits/is_enum.hpp boost/type_traits/is_convertible.hpp boost/type_traits/is_abstract.hpp boost/type_traits/is_class.hpp This causes a problem for standards-compliant compilers because, depending on where you enter the cycle, some template's declaration will not be seen before it is used. For example, entering at is_scalar.hpp (which happens when you include optional.hpp) causes the definition of is_class<> to be seen before the declaration of is_scalar<>, but the former uses the later. The problem was introduced in the change from 1.32 to 1.33, when is_abstract.hpp started being #included by is_convertible.hpp. For reasons I still don't fully understand, this doesn't always actually cause a problem. I think it has to do with the mysterious BOOST_NO_IS_ABSTRACT macro; my understanding of the intricacies of Boost configuration is very limited. The place I ran into this was using an EDG-based front end to parse the preprocessed output of Sun CC 5.7 on solaris-sparc; input is "#include <boost/optional.hpp>"; using Boost 1.33.0 or 1.33.1. I can't repro on linux or with gcc, nor with the latest CVS version of Boost. But regardless, the cycle is still present in the latest CVS, and cyclic header dependencies are usually a bug. -Scott

This causes a problem for standards-compliant compilers because, depending on where you enter the cycle, some template's declaration will not be seen before it is used. For example, entering at is_scalar.hpp (which happens when you include optional.hpp) causes the definition of is_class<> to be seen before the declaration of is_scalar<>, but the former uses the later.
The problem was introduced in the change from 1.32 to 1.33, when is_abstract.hpp started being #included by is_convertible.hpp.
For reasons I still don't fully understand, this doesn't always actually cause a problem. I think it has to do with the mysterious BOOST_NO_IS_ABSTRACT macro; my understanding of the intricacies of Boost configuration is very limited. The place I ran into this was using an EDG-based front end to parse the preprocessed output of Sun CC 5.7 on solaris-sparc; input is "#include <boost/optional.hpp>"; using Boost 1.33.0 or 1.33.1. I can't repro on linux or with gcc, nor with the latest CVS version of Boost.
But regardless, the cycle is still present in the latest CVS, and cyclic header dependencies are usually a bug.
This has come up before: For any given specific compiler (the ones we know about and support in Boost.Config) the dependency graph is not cyclic, but is different from compiler to compiler. However, when using a front end about which we know nothing, it's possible to have a configuration setup that fools the code into doing the wrong thing. Anyway, I'll change the config so that not setting BOOST_NO_IS_ABSTRACT always takes a non-cyclic path. John.

"John Maddock" <john@johnmaddock.co.uk> writes:
This causes a problem for standards-compliant compilers because, depending on where you enter the cycle, some template's declaration will not be seen before it is used. For example, entering at is_scalar.hpp (which happens when you include optional.hpp) causes the definition of is_class<> to be seen before the declaration of is_scalar<>, but the former uses the later.
The problem was introduced in the change from 1.32 to 1.33, when is_abstract.hpp started being #included by is_convertible.hpp.
For reasons I still don't fully understand, this doesn't always actually cause a problem. I think it has to do with the mysterious BOOST_NO_IS_ABSTRACT macro; my understanding of the intricacies of Boost configuration is very limited. The place I ran into this was using an EDG-based front end to parse the preprocessed output of Sun CC 5.7 on solaris-sparc; input is "#include <boost/optional.hpp>"; using Boost 1.33.0 or 1.33.1. I can't repro on linux or with gcc, nor with the latest CVS version of Boost.
But regardless, the cycle is still present in the latest CVS, and cyclic header dependencies are usually a bug.
This has come up before: For any given specific compiler (the ones we know about and support in Boost.Config) the dependency graph is not cyclic, but is different from compiler to compiler.
However, when using a front end about which we know nothing, it's possible to have a configuration setup that fools the code into doing the wrong thing. Anyway, I'll change the config so that not setting BOOST_NO_IS_ABSTRACT always takes a non-cyclic path.
I think it should be possible to arrange things so that even a naive look at what-includes-what won't produce this sort of confusion, and that would probably be worth it in the long run. -- Dave Abrahams Boost Consulting www.boost-consulting.com
participants (3)
-
David Abrahams
-
John Maddock
-
Scott McPeak