c++ preprocessor macro errors - c++

Decided to make the life easier I wrote following macros to simplify logger invocation:
#define LOG(level_, message_) \
InfraLogger::instance()->log(level_, \
boost::filesystem::path(__FILE__).filename().string(), \
__FUNCTION__, static_cast<std::ostringstream&>(std::ostringstream().flush() << message_).str(), __LINE__ )
#define LOG_DEBUG (message_) \
InfraLogger::instance()->log(log_debug, \
boost::filesystem::path(__FILE__).filename().string(), \
__FUNCTION__, static_cast<std::ostringstream&>(std::ostringstream() << message_).str(), __LINE__ )
As you can see the only difference is in omitting level_ argument in LOG_DEBUG macro, putting the explicit enumeration value instead.
Invocation is as follows:
LOG(log_info, "This is" << "Test message");
LOG_DEBUG("This is" << "Test message");
But. While the former compiles and works perfectly, the latter gives the following set of errors:
I'm totally stuck with this one (tried googling but not reaaly sure what to google for). Hope someone will shed some light.
Thanks in advance

Related

How to implement a standard-compliant assert macro with an optional formatted message?

What's the way to implement a standard-compliant assert macro with an optional formatted message?
What I have works in clang, but (correctly) triggers the -Wgnu-zero-variadic-macro-arguments warning if it is turned on (e.g. via -Wpedantic) when the macro is used without the optional message. Wandbox
#define MyAssert(expression, ...) \
do { \
if(!(expression)) \
{ \
printf("Assertion error: " #expression " | " __VA_ARGS__); \
abort(); \
} \
} while(0)
One needs to really use the preprocessor to the max in order to differentiate no additional arguments from the case where they are present. But with Boost.PP one can do this:
#include <boost/preprocessor/variadic/size.hpp>
#include <boost/preprocessor/arithmetic/sub.hpp>
#include <boost/preprocessor/logical/bool.hpp>
#include <boost/preprocessor/cat.hpp>
#define MyAssert(...) BOOST_PP_CAT(MY_ASSERT,BOOST_PP_BOOL(BOOST_PP_SUB(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), 1)))(__VA_ARGS__)
#define MY_ASSERT0(expr) MY_ASSERT1(expr,)
#define MY_ASSERT1(expression, ...) \
do { \
if(!(expression)) \
{ \
std::printf("Assertion error: " #expression " | " __VA_ARGS__); \
std::abort(); \
} \
} while(0)
MyAssert must accept at least one argument (standard). Then we count the arguments, subtract one, and turn to a boolean (0 or 1). This 0 or 1 is concatenated to the token MY_ASSERT to form a macro name, to which we proceed to forward the arguments.
MY_ASSERT1 (with args), is your original macro. MY_ASSERT0 substitutes itself with MY_ASSERT1(expr,), the trailing comma means we pass another argument (thus fulfilling the requirement for the one extra argument), but it is an empty token sequence, so it does nothing.
You can see it live.
Since we already went down this rabbit hole, if one doesn't want to pull in Boost.PP the above can be accomplished with the usual argument counting trick, slightly adapted. First, we must decide on a maximum limit for the arguments we allow. I chose 20, you can choose more. We'll need the typical CONCAT macro, and this macro here:
#define HAS_ARGS(...) HAS_ARGS_(__VA_ARGS__,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,)
#define HAS_ARGS_(a1,a2,a3,a4,a5,b1,b2,b3,b4,b5,c1,c2,c3,c4,c5,d1,d2,d3,d4,d5,e, N, ...) N
It's argument counting, but with a twist. When __VA_ARGS__ is a single argument (no extra ones), the N resolved as 0. Otherwise, it is resolved as 1. There can be up to 20 extra arguments after the expression, any number of which will resolve to the same 1. Now we just plug it into the same place we used boost before:
#define MyAssert(...) CONCAT(MY_ASSERT, HAS_ARGS(__VA_ARGS__))(__VA_ARGS__)
You can tinker with it here
I have a solution which I'm not particularly proud of..
We can obtain the first argument in plain form and as a string using:
#define VA_ARGS_HEAD(N, ...) N
#define VA_ARGS_HEAD_STR(N, ...) #N
Note that in usage, in order to not get warnings, you should do VA_ARGS_HEAD(__VA_ARGS__, ) (with the extra ,) so that VA_ARGS_HEAD is never used with a single parameter (trick taken from StoryTeller's answer).
We define the following helper function:
#include <stdarg.h>
#include <stdio.h>
inline int assertionMessage(bool, const char *fmt, ...)
{
int r;
va_list ap;
va_start(ap, fmt);
r = vprintf(fmt, ap);
va_end(ap);
return r;
}
When the assertion has a format string, the function would work with __VA_ARGS__ as is, however when the bool is the only argument, we're missing a format string. That's why we'll add another empty string after __VA_ARGS__ when invoking it:
#define MyAssert(...) \
do { \
if(!(VA_ARGS_HEAD(__VA_ARGS__, ))) \
{ \
printf("Assertion error: %s | ", VA_ARGS_HEAD_STR(__VA_ARGS__, )); \
assertionMessage(__VA_ARGS__, ""); \
abort(); \
} \
} while(0)
Note that assertionMessage doesn't have printf in its name. This is deliberate and intended to avoid the compiler giving format-string related warnings for its invocations with the extra "" argument. The down-side for this is that we don't get the format-string related warnings when they are helpful.
The basic solution is to use << on cerr:
#define MyAssert(expression, msg) \
do { \
if(!(expression)) \
{ \
std::cerr << msg; \
abort(); \
} \
} while(0)
This solution uses C++ streams, so you can format the output as you see fit. Actually this is a simplification of a C++17 solution that I'm using to avoid temporaries (people tend to use + instead of << with this solution, triggering some efficiency warnings).
Use it then like this:
MyAssert(true, "message " << variable << " units");
I think the optionality is bogus here, as you are outputting "Assertion error:" meaning that you expect a message.

String variable expansion in debug macro

I am trying to write a debug macro in the common subset of C and C++. This is what I've come up with so far:
#define OUTPUT_ERROR(...) printf("%s(%d) : %s() : %s\n", __FILE__, __LINE__, __func__, #__VA_ARGS__)
Unfortunately, I cannot figure out how to give it variables to output. Is there any way to force a variable to be expanded at runtime? For example:
OUTPUT_ERROR("%s was broken", my_var);
or simply in place
OUTPUT_ERROR(my_var + "some text");
It seems to me that you're trying to cram too much into one printf() call. You don't need to do that. In particular, to support usage such as your first example:
OUTPUT_ERROR("%s was broken", my_var);
you could easily split the output over multiple printf() calls with a macro like this:
#define OUTPUT_ERROR(...) do { \
printf("%s(%d) : %s() : ", __FILE__, __LINE__, __func__); \
printf(__VA_ARGS__); \
putchar('\n'); \
} while (0)
I think you're looking to define a macro prepending some debugging information to your formatted log.
To achieve this, you can use the following macro :
#define LOG(format, ...) \
printf("%s(%d) : %s() " format, __FILE__, __LINE__, __FUNCTION__, ##__VA_ARGS__)
This way LOG("%d", 123) will expand to printf("%s(%d) : %s() " "%s", __FILE__, __LINE__, __FUNCTION__, 123).
As consecutive string literals are merged ("a" "b" is equivalent to "ab"), the printf format is correctly built.
Also note the use of , ## __VA_ARGS__. This is a GNU extension (see https://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html) that allows empty variadic arguments.
This technique will however fail if format is not a string literal.
See an example here : http://ideone.com/gMnaES

Invalid argument count in a variadic macro

I am trying to create a macro that would iterate over a defined list of terms, and for each invoke another macro, possibly with additional argument list. Here is what I have got:
#define ITERATE_OVER_TERMS(MACRO, ...) \
MACRO(Term1, __VA_ARGS__) \
MACRO(Term2, __VA_ARGS__) \
MACRO(Term3, __VA_ARGS__) \
... and so on
However, when I was trying to use it with Visual Studio 2015, i get an error
warning C4003: not enough actual parameters for macro 'BODY'
where BODY is the name of the macro passed as the MACRO argument. While technically a warning, it shows that something has gone wrong with the expansion.
In an attempt to narrow down the error, I reduced my example to the following:
#include <iostream>
#define ITERATE(MACRO, ...) \
MACRO(1, __VA_ARGS__) MACRO(2, __VA_ARGS__)
#define BODY(IterationArg, Arg1, Arg2) \
std::cout << IterationArg << Arg1 << Arg2 << std::endl;
int main() {
ITERATE(BODY, 8, 9)
return 0;
}
It gives me the error as shown above, while I expected it to compile succesfully and produce the output
189
289
It does seem to compile with g++, but not Visual Studio.
What am I missing? Is there some walkaround for this to work?
The problem is that Visual Studio expands __VA_ARGS__ after they are being passed into a subsequent macro, and not before. This has caused problems in the past as well, for example here --
Why does this variadic argument count macro fail with VC++?
In your case, consider a simple change in the code:
#include <iostream>
#define ITERATE(MACRO, ...) \
MACRO(1, __VA_ARGS__) MACRO(2, __VA_ARGS__)
#define BODY(IterationArg, Arg1, Arg2) \
std::cout << #Arg1 << std::endl;
int main() {
ITERATE(BODY, 8, 9)
return 0;
}
The argument #Arg1 is stringified, showing us its contents in the output:
8, 9
8, 9
Not what we expected, huh?
A solution is the same as in the linked question: force an expansion through a dummy EXPAND macro:
#define EXPAND(x) x
#define ITERATE(MACRO, ...) \
EXPAND(MACRO(1, __VA_ARGS__)) EXPAND(MACRO(2, __VA_ARGS__))
This gives you the desired result both in VS and gcc.

How to change macro function argument expansion ordering?

I have the following code:
#include <iostream>
#include <stdexcept>
#define TRACE_MACRO(EnterText) \
class CTrace \
{ \
public: \
CTrace() \
{ \
std::cout << EnterText; \
} \
private:\
};
#define DO_TRACE TRACE_MACRO("[ENTER] " __FUNCTION__ "\r\n") CTrace trace
static void test()
{
DO_TRACE;
}
int main(int, char**)
{
DO_TRACE;
test();
return 0;
}
Which outputs:
[ENTER] main::CTrace::CTrace
[ENTER] test::CTrace::CTrace
How can I write the macro such that __FUNCTION__ is expanded first so that the output becomes:
[ENTER] main
[ENTER] test
I attempted to create a sub macro called DO_TRACE2 that forwards the arguments, but this results in the same output.
If this isn't possible then what about a macro that will compile time substring the text to strip off the CTrace::CTrace part of the string?
Edit: Note that I don't want to pass a pointer to a compile time string to this class, I want the call to std::cout to appear as if I had actually manually wrote std::cout << "main";
Untested, but here's a simple rearrangement that might work:
#define TRACE_MACRO \
class CTrace \
{ \
public: \
CTrace(const char* text) \
{ \
std::cout << text; \
} \
private:\
};
#define DO_TRACE TRACE_MACRO CTrace trace("[ENTER] " __FUNCTION__ "\r\n")
Jimmy asked
is it necessary to define a whole new class in the macro def?
And you replied:
#Jimmy no, I just wanted the call to std::cout to be using const
static compile time strings rather than a pointer to a compile time
string, if that makes sense.
So why not just drop the class:
#define DO_TRACE std::cout << "[ENTER] " << __FUNCTION__ << "\r\n"
This will output:
[ENTER] main
[ENTER] test
and uses the const static compile time string....
I probably missed something, just tell me, I'll delete this post....
By the way, I compiled the code from your post using GNU GCC version 4.8.1 from http://www.compileonline.com/compile_cpp_online.php. It outputs
[ENTER] CTrace
[ENTER] CTrace
So looks like FUNCTION macro is resolved differenetly by compilers...

Why would you use the __LINE__ macro in C++

I am trying to figure out how people use the __LINE__ macro at work. How do you guys use it?
You can use __LINE__, along with __FILE__, to report where problems occur in the source code.
Consider, for example, the assert() macro - this wording from the C99 standard, but C++ is similar, except it does not mention __func__:
When it is executed, if expression (which shall have a scalar type) is false (that is,
compares equal to 0), the assert macro writes information about the particular call that
failed (including the text of the argument, the name of the source file, the source line
number, and the name of the enclosing function — the latter are respectively the values of
the preprocessing macros __FILE__ and __LINE__ and of the identifier
__func__) on the standard error stream in an implementation-defined format.
#define assert(x) (void)(((x)==0)?_Assert(#x,__FILE__,__LINE__,__func__):0)
An even simpler example, here's a macro I occasionally use when all other forms of debugging have failed:
#define GOT_HERE std::cout << "At " __FILE__ ":" << __LINE__ << std::endl
Then when your code is mysteriously crashing and taking the device down with it, you can at least sprinkle this macro liberally into the source, in the hope that it will let you narrow down where the crash occurs (and after how many repeats). In practice you might not write to std::cout, but rather use the lowest-level, most reliable character output available on the platform.
I wrote a wrapper for malloc:
#if DEBUG
#define malloc(s) debugging_malloc(s, __FILE__, __LINE__)
#define free(p) debugging_free(p)
// Also, calloc(), strdup(), realloc() should be wrapped.
#endif // DEBUG
Within the wrapper, allocations are tracked according to the file and line number at which they occur. When the program exits, a utility functions outputs a list of any unfreed blocks.
If you are using gcc, it also gives you __FUNCTION__, which is really nice. C99-compliant compilers also have __func__, just as handy.
Most of the answers so far have involved some sort of debugging code. Another use of __LINE__ (and possibly __FILE__) is to enable a macro to generate a unique identifier each time it's called. This implementation of coroutines in C uses these macros to generate labels for a case statement, so it can jump to the last line you called yield from.
Just like this:
$ cat line.cc
#include <iostream>
int main(void) {
std::cout << "Hello, world from " << __LINE__ << std::endl;
return 0;
}
$ g++ -o line line.cc
$ ./line
Hello, world from 4
$
if (something truly impossible has happened) {
fprintf(stderr, "Value of PI less than 3 detected at %s line %d\n", __FILE__, __LINE__);
}
It's especially handy in CPP macros that detect intolerable conditions.
It's really just for debugging/logging purposes. I rarely use it because I tend to rely on debuggers like gdb more often.
But you could always use it when outputting debug information.
void dosomething(Object* o)
{
if (!o) {
std::cerr << __FILE__ << ":" << __LINE__ << ": o is NULL!\n";
abort();
}
}
Just to vaguely quote from the top of my head:
#define assert(e) ((e) ? (void)0 : printf("Assertion failed %s, %s : %s", #e, __FILE__, __LINE__))