From 8a352e253a0f0e988ce2f374b4b1ebeb67462451 Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Thu, 9 Oct 2025 17:25:18 +0200 Subject: [PATCH 1/2] Use the do {} while (false) idiom for BOOST_TEST_THROWS() and BOOST_TEST_NO_THROW() Reason: Common hygiene for multi-line macros. Makes things like if (condition) BOOST_TEST_THROWS(...); else ... work correctly. Also, it doesn't generate an empty statement (which compilers may warn about) when the user adds a semicolon (which they usually do). --- include/boost/core/lightweight_test.hpp | 54 +++++++++++++------------ 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/include/boost/core/lightweight_test.hpp b/include/boost/core/lightweight_test.hpp index 43baea05..b6fba351 100644 --- a/include/boost/core/lightweight_test.hpp +++ b/include/boost/core/lightweight_test.hpp @@ -552,38 +552,42 @@ inline void lwt_init() #define BOOST_TEST_ALL_WITH(begin1, end1, begin2, end2, predicate) ( ::boost::detail::test_all_with_impl(BOOST_LIGHTWEIGHT_TEST_OSTREAM, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, begin1, end1, begin2, end2, predicate) ) #ifndef BOOST_NO_EXCEPTIONS - #define BOOST_TEST_THROWS( EXPR, EXCEP ) \ - try { \ - EXPR; \ - ::boost::detail::throw_failed_impl \ - (#EXPR, #EXCEP, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \ - } \ - catch(EXCEP const&) { \ - ::boost::detail::test_results(); \ - } \ - catch(...) { \ - ::boost::detail::throw_failed_impl \ - (#EXPR, #EXCEP, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \ - } \ + #define BOOST_TEST_THROWS( EXPR, EXCEP ) \ + do { \ + try { \ + EXPR; \ + ::boost::detail::throw_failed_impl \ + (#EXPR, #EXCEP, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \ + } \ + catch(EXCEP const&) { \ + ::boost::detail::test_results(); \ + } \ + catch(...) { \ + ::boost::detail::throw_failed_impl \ + (#EXPR, #EXCEP, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \ + } \ + } while (false) // #else - #define BOOST_TEST_THROWS( EXPR, EXCEP ) + #define BOOST_TEST_THROWS( EXPR, EXCEP ) do {} while (false) #endif #ifndef BOOST_NO_EXCEPTIONS -# define BOOST_TEST_NO_THROW(EXPR) \ - try { \ - EXPR; \ - } catch (const std::exception& e) { \ - ::boost::detail::no_throw_failed_impl \ - (#EXPR, e.what(), __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \ - } catch (...) { \ - ::boost::detail::no_throw_failed_impl \ - (#EXPR, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \ - } +# define BOOST_TEST_NO_THROW(EXPR) \ + do { \ + try { \ + EXPR; \ + } catch (const std::exception& e) { \ + ::boost::detail::no_throw_failed_impl \ + (#EXPR, e.what(), __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \ + } catch (...) { \ + ::boost::detail::no_throw_failed_impl \ + (#EXPR, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \ + } \ + } while (false) // #else -# define BOOST_TEST_NO_THROW(EXPR) { EXPR; } +# define BOOST_TEST_NO_THROW(EXPR) do { EXPR; } while (false) #endif #endif // #ifndef BOOST_CORE_LIGHTWEIGHT_TEST_HPP From 40fda50ae1d421eab3e45608f019cc81eaee908b Mon Sep 17 00:00:00 2001 From: Gennaro Prota Date: Mon, 13 Oct 2025 17:36:12 +0200 Subject: [PATCH 2/2] Omit do {} while (false) for MSVC versions prior to 2015 Reason: See the new code comment. --- include/boost/core/lightweight_test.hpp | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/include/boost/core/lightweight_test.hpp b/include/boost/core/lightweight_test.hpp index b6fba351..267ba66b 100644 --- a/include/boost/core/lightweight_test.hpp +++ b/include/boost/core/lightweight_test.hpp @@ -551,9 +551,22 @@ inline void lwt_init() #define BOOST_TEST_ALL_EQ(begin1, end1, begin2, end2) ( ::boost::detail::test_all_eq_impl(BOOST_LIGHTWEIGHT_TEST_OSTREAM, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, begin1, end1, begin2, end2) ) #define BOOST_TEST_ALL_WITH(begin1, end1, begin2, end2, predicate) ( ::boost::detail::test_all_with_impl(BOOST_LIGHTWEIGHT_TEST_OSTREAM, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, begin1, end1, begin2, end2, predicate) ) +#if !defined(BOOST_MSVC) || (BOOST_MSVC >= 1900) +// The usual idiom for multiline macros. But disabled for MSVC versions +// prior to 2015, which would emit a "conditional expression is constant" +// warning that we could not silence with a _Pragma, despite this being +// the same thing described here: +// +// . +// + #define BOOST_LWT_DETAIL_DO_WHILE_FALSE( x ) do { x } while (false) +#else + #define BOOST_LWT_DETAIL_DO_WHILE_FALSE( x ) x +#endif + #ifndef BOOST_NO_EXCEPTIONS #define BOOST_TEST_THROWS( EXPR, EXCEP ) \ - do { \ + BOOST_LWT_DETAIL_DO_WHILE_FALSE( \ try { \ EXPR; \ ::boost::detail::throw_failed_impl \ @@ -566,15 +579,15 @@ inline void lwt_init() ::boost::detail::throw_failed_impl \ (#EXPR, #EXCEP, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \ } \ - } while (false) + ) // #else - #define BOOST_TEST_THROWS( EXPR, EXCEP ) do {} while (false) + #define BOOST_TEST_THROWS( EXPR, EXCEP ) BOOST_LWT_DETAIL_DO_WHILE_FALSE((void)0;) #endif #ifndef BOOST_NO_EXCEPTIONS # define BOOST_TEST_NO_THROW(EXPR) \ - do { \ + BOOST_LWT_DETAIL_DO_WHILE_FALSE( \ try { \ EXPR; \ } catch (const std::exception& e) { \ @@ -584,10 +597,10 @@ inline void lwt_init() ::boost::detail::no_throw_failed_impl \ (#EXPR, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION); \ } \ - } while (false) + ) // #else -# define BOOST_TEST_NO_THROW(EXPR) do { EXPR; } while (false) +# define BOOST_TEST_NO_THROW(EXPR) BOOST_LWT_DETAIL_DO_WHILE_FALSE(EXPR;) #endif #endif // #ifndef BOOST_CORE_LIGHTWEIGHT_TEST_HPP