Opened 7 years ago
Closed 6 years ago
#11998 closed Bugs (fixed)
Static const variables cannot be logged
Reported by: | Owned by: | Andrey Semashev | |
---|---|---|---|
Milestone: | To Be Determined | Component: | log |
Version: | Boost 1.60.0 | Severity: | Problem |
Keywords: | log static const | Cc: |
Description
Static const variables cannot be logged for me any more. I am using RHEL 7.1 and the Intel icpc for my programms (boost compiled with gcc 4.8.3)
The following code does not work in 1.60.0 but does in 1.59.0 Maybe it has to do with the changes regarding formatting_ostream #11549 or #11545
Code:
/* * File: main.cpp * Author: hschall * * Created on February 18, 2016, 6:53 AM */ #include <cstdlib> #define BOOST_LOG_DYN_LINK #include <boost/log/trivial.hpp> class TestStaticError{ public: static void doLog(){ BOOST_LOG_TRIVIAL(debug) << myVar; } private: static const unsigned int myVar = 1337; }; class TestStaticWorking{ public: static void doLog(){ BOOST_LOG_TRIVIAL(debug) << (unsigned int)myVar; } private: static const unsigned int myVar = 1337; }; using namespace std; /* * */ int main(int argc, char** argv){ TestStaticWorking::doLog(); // Works // Works in 1.59.0 //TestStaticError::doLog(); // main.cpp:21: undefined reference to `TestStaticError::myVar' return 0; }
Change History (4)
comment:1 by , 7 years ago
comment:2 by , 7 years ago
The workaround is just to show that this behaviour relates to the static variable.
I compile with C++11 (but tested it also with C++98 and C++14). I did test it with the GCC (4.8.3) now aswell, same behaviour.
Wether it is a bug or not, it depends on the boost library version, which is strange.
comment:3 by , 6 years ago
I see similar problem using bitfields:
I took the example from http://www.boost.org/doc/libs/1_61_0/libs/log/example/doc/tutorial_trivial_flt.cpp and added a bitfield print:
#include <boost/log/core.hpp> #include <boost/log/trivial.hpp> #include <boost/log/expressions.hpp> namespace logging = boost::log; //[ example_tutorial_trivial_with_filtering void init() { logging::core::get()->set_filter ( logging::trivial::severity >= logging::trivial::info ); } struct BF { unsigned int b : 8; BF() : b(0) {} }; int main(int, char*[]) { init(); BF bf; BOOST_LOG_TRIVIAL(info) << "An informational severity message " << bf.b; return 0; } //]
With boost 1.60 I got a compilation error:
cannot bind bitfield 'bf.BF::b' to 'unsigned int&'
With boost 1.57 the code is compiled and run (prints: [2016-09-19 20:21:33.018112] [0x000007fd1d5be672] [info] An informational severity message 0)
comment:4 by , 6 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Should be fixed in https://github.com/boostorg/log/commit/ea486c1468589b590a78ab88686dbc28ef2c91f5. Thanks for the report.
I don't think this is a bug in the library.
The static constant members have to be defined in some (one) translation unit, which gives them storage. In C++11 and later this is required if a reference to the variable is taken, which happens when you call the
operator<<
. In pre-C++11 versions of the language, IIRC, the definition is required unconditionally.The type conversion that you use as a workaround makes the
operator<<
bind the reference to a temporary, that's why it works. I'm not sure how it works differently in 1.59 since I don't see any changes that could lead to that but there were such changes since 1.58 - theoperator<<
overloads could have been chosen differently before, which would result in not taking the reference.However, I can see that your use case could be useful, and I'll see if I can support it in the future.