I have a macro which I use to log, and within the macro I'd like to define a temprecord as follows:
#define MACRO_LOG(...) \
temprecord t; \
logger->logmessage(__VA_ARGS___);
with temprecord() { logger->increaseIndent() }
and in the destructor a decreaseIndent()
.
The association with a name (eg, variable) gives an object scope which controls its lifetime. By not naming an object, it's lifetime is bound
source Why do un-named C++ objects destruct before the scope block ends?
Because the temprecord has lifetime of the scope, if I have
{
MACRO_LOG("stackoverflow example");
MACRO_LOG("stackoverflow example");
}
Outside the scope I will have 0 indent and in the scope 1 and 2 indents. However , as I name my temprecord t I get a redefinition of variable names.. and if I do not declare it I do not get the scope that I want.
How to go about this? I thought of using a container to put the temprecords in, but can't seem to solve the puzzle..
What I wish to accomplish is double indentation in my mentioned scope, and not single indentation within the MACRO_LOG scope.
Macro replacement is just an in-place text replacement. So, given the #define
you have shown, the code:
{
MACRO_LOG("stackoverflow example");
MACRO_LOG("stackoverflow example");
}
Expands to this:
{
temprecord t;
logger->logmessage("stackoverflow example");;
temprecord t;
logger->logmessage("stackoverflow example");;
}
Which should make it obvious why the macro doesn't work when used multiple times in the same scope, since t
is declared multiple times.
There are some different ways you can solve this:
1) wrap the content of MACRO_LOG()
in curly braces so that temprecord t
is in its own scope, eg:
#define MACRO_LOG(...) { \
temprecord t; \
logger->logmessage(__VA_ARGS___); \
}
Which would expand the code to this:
{
{
temprecord t;
logger->logmessage("stackoverflow example");
};
{
temprecord t;
logger->logmessage("stackoverflow example");
};
}
2) append __LINE__
to t
to give each copy of the temprecord
a more unique name, eg:
(See Creating C macro with ## and __LINE__ (token concatenation with positioning macro) )
#define TOKENPASTE(x, y) x ## y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#define MACRO_LOG(...) \
temprecord TOKENPASTE2(t_, __LINE__); \
logger->logmessage(__VA_ARGS___);
Which would expand the code to this:
{
temprecord t_12345;
logger->logmessage("stackoverflow example");;
temprecord t_12347;
logger->logmessage("stackoverflow example");;
}
3) use the comma operator to define a nameless variable in the same expression that calls logmessage()
, the variable will not go out of scope until logmessage()
returns, eg:
#define MACRO_LOG(...) temprecord(), logger->logmessage(__VA_ARGS___);
Which would expand the code to this:
{
temprecord(), logger->logmessage("stackoverflow example");;
temprecord(), logger->logmessage("stackoverflow example");;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.