Reputation: 2730
I am having trouble with a #define I have made. For some reason it is not checking all the arguments in the statement.
THROW_AND_LOG(Foo::Initialize() && Bar::Initialize() && FooBar::Initialize(), "Something() could not Initialize singletons.");
For some reason it is only initializes Foo and then exits the statement. It does not throw or log.
However
THROW_AND_LOG((Foo::Initialize() && Bar::Initialize() && FooBar::Initialize()), "Something() could not Initialize singletons.");
works fine for some reason. (Wrapped all the checks in brackets).
I am going to move everything on to its own seperate line to fix this as its not the best code in the first place. I am curious however of why it would not execute all statements.
Here is the define:
#define THROW_AND_LOG(x, message) if(!x) { throw std::runtime_error(message); \
LOG::v1::MessageSender messageSender("log"); \
LOGGING_ERROR(messageSender,message);}
Upvotes: 0
Views: 63
Reputation: 41301
After the macro expansion,
if(!x)
transforms to
if(!Foo::Initialize() && Bar::Initialize() && FooBar::Initialize())
Foo::Initialize()
presumably returns true
, so !Foo::Initialize()
is false
and other terms are not executed (not mentioning that their meaning has changed to the opposite).
Upvotes: 7
Reputation: 145279
With the macro definition
#define THROW_AND_LOG(x, message) if(!x) { throw std::runtime_error(message); \
LOG::v1::MessageSender messageSender("log"); \
LOGGING_ERROR(messageSender,message);}
the invocation
THROW_AND_LOG(Foo::Initialize() && Bar::Initialize() && FooBar::Initialize(), "Something() could not Initialize singletons.");
yields the condition
if(!Foo::Initialize() && Bar::Initialize() && FooBar::Initialize())
which is equivalent to
if((!Foo::Initialize()) && Bar::Initialize() && FooBar::Initialize())
A good fix is to replace the macro with a function:
void throw_and_log_if(
const bool condition,
const Location& location,
const string& message )
{
LOG::v1::MessageSender messageSender( "log" );
LOGGING_ERROR( messageSender, message ); }
throw std::runtime_error( message );
}
where Location
is some class representing file and line number, which you can pick up via the __FILE__
and __LINE__
macros.
I took the liberty of fixing the bug causing logging to not be performed.
A short term easier fix is to use parenthesis around the x
in the macro's condition.
If you choose that, then do remember to fix the bug in the macro.
Upvotes: 3
Reputation: 224964
It's not expanding the way you think it is. You want (!(x))
in your macro.
Upvotes: 6