<boost/assert.hpp> uses BOOST_NORETURN in the declarations of assertion_failed / assertion_failed_msg, but the #include <boost/config.hpp> that defines it comes later in the file, and only inside one of the BOOST_ASSERT branches. So when BOOST_ASSERT_HANDLER_IS_NORETURN is defined and <boost/config.hpp> has not already been included by something else, the header does not compile.
Repro
#define BOOST_ASSERT_HANDLER_IS_NORETURN
#include <boost/assert.hpp>
int main() {}
$ clang++ -std=c++17 -fsyntax-only -I <boost> repro.cpp
boost/assert.hpp:36:5: error: unknown type name 'BOOST_NORETURN'
36 | BOOST_NORETURN
| ^
boost/assert.hpp:41:5: error: unknown type name 'BOOST_NORETURN'
41 | BOOST_NORETURN
| ^
2 errors generated.
Observed with Boost 1.92.0, clang 22, -std=c++17 and -std=c++23 alike. I did not bisect which release introduced it.
Why it usually goes unnoticed
BOOST_NORETURN is only referenced under #if defined(BOOST_ASSERT_HANDLER_IS_NORETURN), and most translation units have already pulled in <boost/config.hpp> transitively through some other Boost header before they reach <boost/assert.hpp>. It surfaces when a project defines that macro project-wide and a translation unit happens to reach assert.hpp first — which is easy to hit via a force-include or a precompiled header.
Suggested fix
Move the #include <boost/config.hpp> above the namespace boost block, so the declarations that use BOOST_NORETURN are preceded by its definition. <boost/config.hpp> has its own include guards, so hoisting it does not conflict with assert.hpp deliberately having none (the note at the top of the file), and the later include inside the BOOST_ENABLE_ASSERT_HANDLER branch then becomes redundant rather than wrong.
A downstream workaround, for anyone who finds this before it is fixed: force-include <boost/config.hpp> on the command line (-include boost/config.hpp, /FIboost/config.hpp).
<boost/assert.hpp>usesBOOST_NORETURNin the declarations ofassertion_failed/assertion_failed_msg, but the#include <boost/config.hpp>that defines it comes later in the file, and only inside one of theBOOST_ASSERTbranches. So whenBOOST_ASSERT_HANDLER_IS_NORETURNis defined and<boost/config.hpp>has not already been included by something else, the header does not compile.Repro
Observed with Boost 1.92.0, clang 22,
-std=c++17and-std=c++23alike. I did not bisect which release introduced it.Why it usually goes unnoticed
BOOST_NORETURNis only referenced under#if defined(BOOST_ASSERT_HANDLER_IS_NORETURN), and most translation units have already pulled in<boost/config.hpp>transitively through some other Boost header before they reach<boost/assert.hpp>. It surfaces when a project defines that macro project-wide and a translation unit happens to reachassert.hppfirst — which is easy to hit via a force-include or a precompiled header.Suggested fix
Move the
#include <boost/config.hpp>above thenamespace boostblock, so the declarations that useBOOST_NORETURNare preceded by its definition.<boost/config.hpp>has its own include guards, so hoisting it does not conflict withassert.hppdeliberately having none (the note at the top of the file), and the later include inside theBOOST_ENABLE_ASSERT_HANDLERbranch then becomes redundant rather than wrong.A downstream workaround, for anyone who finds this before it is fixed: force-include
<boost/config.hpp>on the command line (-include boost/config.hpp,/FIboost/config.hpp).