Modify

Ticket #11998 (closed Bugs: fixed)

Opened 11 months ago

Last modified 4 months ago

Static const variables cannot be logged

Reported by: Hendrik Schall <torres@…> Owned by: andysem
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;
}

Attachments

Change History

comment:1 Changed 11 months ago by andysem

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 - the operator<< 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.

comment:2 Changed 11 months ago by Hendrik Schall <torres@…>

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 Changed 4 months ago by o.z

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 Changed 4 months ago by andysem

  • Status changed from new to closed
  • Resolution set to fixed
View

Add a comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
The resolution will be deleted. Next status will be 'reopened'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.