diff --git a/src/common/dout.h b/src/common/dout.h index 4cd60efff8fef..db68a042a7f1b 100644 --- a/src/common/dout.h +++ b/src/common/dout.h @@ -144,17 +144,24 @@ struct is_dynamic> : public std::true_type {}; #else #define dout_impl(cct, sub, v) \ do { \ - const bool should_gather = [&](const auto cctX) { \ - if constexpr (ceph::dout::is_dynamic::value || \ - ceph::dout::is_dynamic::value) { \ + const bool should_gather = [&](const auto cctX, auto sub_, auto v_) { \ + /* The check is performed on `sub_` and `v_` to leverage the C++'s \ + * guarantee on _discarding_ one of blocks of `if constexpr`, which \ + * includes also the checks for ill-formed code (`should_gather<>` \ + * must not be feed with non-const expresions), BUT ONLY within \ + * a template (thus the generic lambda) and under the restriction \ + * it's dependant on a parameter of this template). \ + * GCC prior to v14 was not enforcing these restrictions. */ \ + if constexpr (ceph::dout::is_dynamic::value || \ + ceph::dout::is_dynamic::value) { \ return cctX->_conf->subsys.should_gather(sub, v); \ } else { \ - /* The parentheses are **essential** because commas in angle \ - * brackets are NOT ignored on macro expansion! A language's \ - * limitation, sorry. */ \ - return (cctX->_conf->subsys.template should_gather()); \ + constexpr auto sub_helper = static_cast(sub); \ + constexpr auto v_helper = static_cast(v); \ + return cctX->_conf->subsys.template should_gather(); \ } \ - }(cct); \ + }(cct, sub, v); \ \ if (should_gather) { \ ceph::logging::MutableEntry _dout_e(v, sub); \