0

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.61 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)

notice that:

  1. cout of-course can handle this (so I think it is not just a backward compatibility issue, but a bug)
  2. boost 1.61 can handle const bitfield, e.g BOOST_LOG_TRIVIAL(info) << "An informational severity message " << BF().b;

I'm searching for workaround. Suggestions?

o.z
  • 1,086
  • 14
  • 22

2 Answers2

1

The easiest workaround is to convert the bitfield to a full integer. You can do that with a cast:

BOOST_LOG_TRIVIAL(info) << "An informational severity message "
    << static_cast< unsigned int >(BF().b);
Andrey Semashev
  • 10,046
  • 1
  • 17
  • 27
  • I guess there is no solution via boost::log itself currently, right? Is there a plans to fix it in the future? – o.z Sep 21 '16 at 11:56
  • Unless you want to patch Boost.Log, no, there is no transparent solution. There is https://svn.boost.org/trac/boost/ticket/11998 which has the same origin as your problem, you can add your case to that ticket as well. – Andrey Semashev Sep 22 '16 at 23:31
  • If you got a petch, I'll be super glad to have it. Tnx! – o.z Sep 24 '16 at 18:12
  • I found a workaround - I searched in record_ostream.hpp and saw the additional code you added there and the helpful note attached and got the direction... – o.z Sep 26 '16 at 19:04
0

I found a workaround - overloading operator<< for record_ostream of all unsigned integers:

#include <sys/types.h>

namespace logging = boost::log;

typedef logging::basic_formatting_ostream<  logging::record_ostream::char_type > formatting_ostream_type;

logging::record_ostream& operator << (logging::record_ostream& strm, u_int8_t value) {
    static_cast< formatting_ostream_type& >(strm) << value;
    return strm;
}

logging::record_ostream& operator << (logging::record_ostream& strm, u_int16_t value) {
    static_cast< formatting_ostream_type& >(strm) << value;
    return strm;
}

logging::record_ostream& operator << (logging::record_ostream& strm, u_int32_t value) {
    static_cast< formatting_ostream_type& >(strm) << value;
    return strm;
}

logging::record_ostream& operator << (logging::record_ostream& strm, u_int64_t value) {
    static_cast< formatting_ostream_type& >(strm) << value;
    return strm;
}

The integers got copied (are taken by value) so there is no bind issue

o.z
  • 1,086
  • 14
  • 22