2

I'm trying to setup boost.log into a project I have. I've followed the examples, but when I try to set a format, the compiler says that format is a read-only reference.

void init() {
    logging::add_console_log(
        std::cout,

        // Compiler says "const boost::parameter::keyword<keywords::tag::format>& is read-only reference".
        keywords::format = "%Timestamp% %Message%",

        keywords::severity = info
    );

    logging::add_common_attributes();
}
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Jazzwave06
  • 1,883
  • 1
  • 11
  • 19
  • 1
    You should learn about the language itself before blindly attempting to write Boost code. This way, one day or another, you'll find yourself in front of a 1000-line long template instantation error, and won't have any idea about what to do. – 3442 Mar 27 '16 at 16:01
  • 1
    Well you could pin-point me what type of error this is. I'm not a beginner in software development (I'm an architect) and I pretty much understand most of the principles. I need to learn C++ to dev a lightweight GlusterFS replacement. Just tell me what kind of error this is and I won't make it ever again, thanks. – Jazzwave06 Mar 27 '16 at 16:29
  • I'm by no means an expert in Boost, but I know that you're trying to modify a read-only variable, as the compiler appropriately tells you. That is basically the answer to your question. – 3442 Mar 27 '16 at 16:31
  • From the documentation: http://www.boost.org/doc/libs/1_58_0/libs/log/doc/html/boost/log/add_console_lo_idp52354704.html: format Specifies a formatter to install into the sink. May be a string that represents a formatter, or a formatter lambda expression (either streaming or Boost.Format-like notation). – Jazzwave06 Mar 27 '16 at 16:39
  • 1
    Also: http://stackoverflow.com/questions/10972818/how-to-change-the-default-formatting-with-boostlogboost-trivial-log. The guy does the same thing as me, yet it seems to work. – Jazzwave06 Mar 27 '16 at 16:45
  • You're assigning a value to `keywords::format` and then evaluating that value into the `format` parameter. Remove `keywords::format =` and you should be okay. Same applies for the other attempt below. Trust me, there are way too many things you seem not to understand about C++, and **really trust me**, C++ is one of the most complicated and feature-full languages ever conceived by mankind. There's a myth that says that no living person knows all of it. You should take a good time to get familiar with it. A Python background is useless here. – 3442 Mar 27 '16 at 16:52
  • 1
    Nope, it's not even compiling. All examples on the boost site put keywords::format before this parameter. – Jazzwave06 Mar 27 '16 at 16:59
  • Of course, it's not compiling because it's not *semantically* valid code (attempts to write to read only memory). However, it's syntatically valid, and in a very obscure way. The code in the answer you mentioned does effectively work. Again, I'm no expert in C++, but C++ is not a language to work with if you don't know it from the inside. It's not as intuitive as it seems first-hand, and it's way too easy to introduce code that compiles, but produces completely unexpected results. You should understand examples, not copy-paste them. Rule #1 is that templates can get way too complicated easily. – 3442 Mar 27 '16 at 17:55
  • @KemyLand: This is how Boost.Log works. I advise against the holier-than-thou approach to teaching until you yourself have the slightest clue what you're talking about. :) – Lightness Races in Orbit Mar 28 '16 at 17:33
  • @BarryTheHatchet: I know the language, but not the bulky Boost libraries. The OP seems to know neither. Please be a little more respectful for my attempts in helping the OP, and then may I consider your empty and irrelevant suggestion. – 3442 Mar 30 '16 at 22:30
  • 1
    @KemyLand: No, _I'm_ asking _you_ to be respectful. So far your comments to the OP have included phrases including: _"You should learn about the language itself before blindly attempting to write Boost code"_, _"Trust me, there are way too many things you seem not to understand about C++"_, _"**trust me**"_... which are somewhat ironic since you fundamentally misunderstood both the code and the question. Just a friendly suggestion to do some research yourself next time! :) – Lightness Races in Orbit Mar 30 '16 at 22:52
  • @BarryTheHatchet: I did never read the function's API. Maybe I didn't used the best words to the OP. However, I attempted to help him based on pitfalls I know he would fall on otherwise. Your presence here is purposeless and so far has helped no one to improve nothing. Please stop doing this. – 3442 Mar 31 '16 at 00:12
  • Sigh. Pot meet kettle. – Lightness Races in Orbit Mar 31 '16 at 09:00
  • Have you tried compiling the nearest example? It could be you're missing a header file include. http://www.boost.org/doc/libs/1_60_0/libs/log/example/doc/tutorial_fmt_string.cpp – JimB May 04 '16 at 11:08
  • It's possible that `keywords::format` is in the wrong namespace. You might want to use the fully specified namespace : `boost::log::keywords::format`. This compiles for me... except I'm having trouble having the logger recognize `"%Severity%`... but that is a functional problem, not a compilation problem. – Mark Lakata Mar 31 '22 at 04:40

1 Answers1

1

My guess is that you're experiencing a compiler bug. The format keyword, as any other keyword declared with BOOST_PARAMETER_KEYWORD from Boost.Parameter, is indeed a constant reference. However, there is a const-qualified assignment operator in boost::parameter::keyword, which should be picked by the compiler.

As a workaround, you can try replacing the keyword with a call to get static function like this:

// Replace this:
keywords::format = "%Timestamp% %Message%"

// with this:
boost::parameter::keyword<keywords::tag::format>::get() = "%Timestamp% %Message%"

Also, please note that the attribute names are case sensitive, and the add_common_attributes function adds a "TimeStamp" attribute, not "Timestamp" (note the upper-case S).

Andrey Semashev
  • 10,046
  • 1
  • 17
  • 27
  • Thanks for the answer, however, the compiler still complains about the immutability of the instance. – Jazzwave06 Mar 28 '16 at 18:38
  • What if you just construct the keyword in place? `boost::parameter::keyword format; format = "%Timestamp% %Message%";` Then, if nothing works, you can try constructing the sink manually and setting up it through the API (see http://www.boost.org/doc/libs/1_60_0/libs/log/doc/html/boost/log/sinks/text_file_backend.html), although you may get similar errors in other parts of the library. Also, what compiler are you using? – Andrey Semashev Mar 29 '16 at 07:41
  • Nope. By the way, it does work, however CLion keeps flagging the line as an error. But the code compiles and work, without warning from gcc (-Wall -Wextra -Werror). I decided to stop the investigation and let it as is, since it works (CLion flags lot of boost code). – Jazzwave06 Mar 29 '16 at 14:31
  • Most IDE-targeting code parsers have to cut some corners to provide a reasonable performance. They may flag valid code as errors or simply fail to parse. In my experience, parsers based on Clang (e.g. in QtCreator) provide the best robustness while having decent performance. BTW, next time it would be nice if you mention in the question that the error comes from the IDE and not the actual compiler. – Andrey Semashev Mar 29 '16 at 19:03