Boost
C++ Libraries
...one of the most highly
regarded and expertly designed C++ library projects in the
world.
— Herb Sutter and Andrei
Alexandrescu, C++
Coding Standards
This is an older version of Boost and was released in 2021. The current version is 1.89.0.
Initially scoped attributes were able to override other attributes with the same name if they were already registered by the time when a scoped attribute encountered. This allowed some interesting use cases like this:
BOOST_LOG_DECLARE_GLOBAL_LOGGER(my_logger, src::logger_mt) void foo() { // This scoped attribute would temporarily replace the existing tag BOOST_LOG_SCOPED_THREAD_TAG("Section", std::string, "In foo"); // This log record will have a "Section" attribute with value "In foo" BOOST_LOG(get_my_logger()) << "We're in foo section"; } int main(int, char*[]) { BOOST_LOG_SCOPED_THREAD_TAG("Section", std::string, "In main"); // This log record will have a "Section" attribute with value "In main" BOOST_LOG(get_my_logger()) << "We're in main section"; foo(); // This log record will have a "Section" attribute with value "In main" again BOOST_LOG(get_my_logger()) << "We're in main section again"; return 0; }
However, this feature introduced a number of safety problems, including thread safety issues, that could be difficult to track down. For example, it was no longer safe to use logger-wide scoped attributes on the same logger from different threads, because the resulting attribute would be undefined:
BOOST_LOG_DECLARE_GLOBAL_LOGGER(my_logger, src::logger_mt) void thread1() { BOOST_LOG_SCOPED_LOGGER_TAG(get_my_logger(), "Tag", std::string, "thread1"); BOOST_LOG(get_my_logger()) << "We're in thread1"; } void thread2() { BOOST_LOG_SCOPED_LOGGER_TAG(get_my_logger(), "Tag", int, 10); BOOST_LOG(get_my_logger()) << "We're in thread2"; } int main(int, char*[]) { BOOST_LOG_SCOPED_LOGGER_TAG(get_my_logger(), "Tag", double, -2.2); BOOST_LOG(get_my_logger()) << "We're in main"; boost::thread t1(&thread1); boost::thread t2(&thread2); t1.join(); t2.join(); // Which "Tag" is registered here? BOOST_LOG(get_my_logger()) << "We're in main again"; return 0; }
There were other issues, like having an attribute set iterator that points to one attribute object, then suddenly without seemingly modifying it it becomes pointing to a different attribute object (of, possibly, a different type). Such behavior could lead to tricky failures that would be difficult to investigate. Therefore this feature was eventually dropped, which simplified the scoped attributes implementation significantly.