Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmnLogger issue in conditional statement #45

Closed
pkazanzides opened this issue May 11, 2016 · 3 comments
Closed

cmnLogger issue in conditional statement #45

pkazanzides opened this issue May 11, 2016 · 3 comments
Assignees
Labels

Comments

@pkazanzides
Copy link
Contributor

The following code does not produce the expected result:

if (condition)
   CMN_LOG_RUN_VERBOSE << "Some text" << std::endl;
else {
   // some more code
}

This appears to be due to the macro used to define CMN_LOG (note that CMN_LOG_RUN_VERBOSE just calls CMN_LOG with a specified lod):

 #define CMN_LOG(lod) \
  if (cmnLogger::GetMask() & cmnLogger::GetMaskFunction() & lod) \
    ((cmnLODOutputMultiplexer(cmnLogger::GetMultiplexer(), lod).Ref()) << cmnLogLevelToString(lod) << " ")

Simplifying the above, CMN_LOG(lod) essentially expands to the following:

if (filterTrue)
   cmnLODOutputMultiplexerRef << user_string << " "

Thus, the original code is compiled as follows, where the else is indented to better indicate the problem:

if (condition)
   if (filterTrue)
       cmnLODOutputMultiplexerRef << "Some text" << " " << std::endl;
   else {
      // some more code
   }

I believe the fix would be to put braces around the entire CMN_LOG macro, e.g.:

 #define CMN_LOG(lod) \
  { if (cmnLogger::GetMask() & cmnLogger::GetMaskFunction() & lod) \
    ((cmnLODOutputMultiplexer(cmnLogger::GetMultiplexer(), lod).Ref()) << cmnLogLevelToString(lod) << " ") }
@adeguet1
Copy link
Collaborator

adeguet1 commented May 13, 2016

Interestingly, gcc gives this warning:

/home/anton/catkin_ws/src/cisst-saw/cisst/cisstCommon/tests/cmnLogLoDTest.cpp:100:12: warning: suggest explicit braces to avoid ambiguous ‘else’ [-Wparentheses]

There were 4 of these in cisst, 2 in cisstMultiTask, 2 in cisstRobot.

Unfortunately adding braces in the macro doesn't solve the issue. The macro is used like this:

   CMN_LOG(level) << "some text" << std::end;

With the braces, this expends as:

  { if (condition) outputStream << } "some text" << std::endl;

which won't compile.

We can change the macro a bit to avoid the bug (I think?) but still triggers the gcc warning:

   // current logic
  #define log(level) \\
  if (needToLog(level)) outputStream <<

  // new logic
  #define log(level) \\
  if (!needToLog(level)) ; else outputStream <<

This is a bit better but programmers should still use braces to avoid the gcc warnings. Testing in branch bug-log: 2ddc476

I tested compilation and unit test for macro CMN_LOG on Windows/VS2013, MacOS clang, Linux gcc and it seems to work. I was expecting some warning because of the no-op before the else but all compilers seem fine with it.

@pkazanzides
Copy link
Contributor Author

This fix seems fine.

@adeguet1
Copy link
Collaborator

In aae4bba:

  • applied same logic CMN_LOG_CLASS macro.
  • tracked most if (cond) CMN_LOG ... calls and added braces to avoid gcc warnings. Behavior is correct in any case but warnings can be alarming

Changes have been merged in devel branch.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants