How to change macro function argument expansion ordering? - c++

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...

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.

C++ macro doesn't substitute? [duplicate]

This question already has answers here:
How can I concatenate twice with the C preprocessor and expand a macro as in "arg ## _ ## MACRO"?
(3 answers)
Closed 7 years ago.
Here is the code.
#include <iostream>
using namespace std;
#define gao falsegao
#define fun(entity) \
void fun_##entity() \
{ \
std::cout << #entity << std::endl; \
}
fun(gao);
int main()
{
fun_gao();
return 0;
}
This program will compile and run at ease. But why? I have already defined gao as falsegao, shouldn't the generated function be void fun_false_gao()? And the output should be false_gao, too.
Please help me solve this puzzle, when will the substitution take place ? what's the principle behind this?
You need a two-leveled fun macro
#define fun_(entity) \
void fun_##entity() \
{ \
std::cout << #entity << std::endl; \
}
#define fun(entity) fun_(entity)
That will work as intended.
Rules of macro substitution of C++ language prevent preprocessor from recursively replacing macro names in tokens adjacent to ## or # operators. You need an additional level of "isolation" to make sure that gao gets replaced with falsegao before it gets to ## or #.
No, the ## operator has higher precedence than parameter substitution. Idiomatically it's wrapped inside a macro:
#define CAT_LITERAL( A, B ) A ## B
#define CAT( A, B ) CAT_LITERAL( A, B )
The same applies to the # operator.
#define STR_LITERAL( LIT ) # LIT
#define STR( PARAM ) STR_LITERAL( PARAM )
So your macro is defined:
#define fun(entity) \
void CAT( fun_, entity ) () \
{ \
std::cout << STR( entity ) << std::endl; \
}

c++ preprocessor macro errors

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

Generic RETURN_IF_FALSE() macro?

I'm trying to clean up some legacy code that contains hundreds of functions with bodies that look like this:
void functionWithSideEffect(Foo* foo)
{
if (foo)
{
// Use `foo' to warm the planet
...
}
}
Obviously, silently failing if a precondition check fails isn't the best idea, so I'd like to refactor this to:
int functionWithSideEffect(Foo* foo)
{
RETURN_IF_FALSE(foo != NULL, "foo is NULL in functionWithSideEffect!");
// Use `foo' to warm the planet
...
}
The following macro seems to work fine for functions that don't return a value:
#define RETURN_IF_FALSE(cond, msg) \
do { \
if (!(cond)) { \
LOG("%s\n", (msg)); \
assert((cond)); \
} \
return; \
} while(0)
And it has the following desirable properties:
It is clear and succinct in usage
It does not silently fail
It will crash in debug builds, but attempt to soldier on in release builds
(Admittedly, for functions returning void, soldiering on in release builds may not always be 'desirable'.)
For functions that do return a value, this macro does the trick:
#define RETURN_VALUE_IF_FALSE(cond, msg, retval ) \
do { \
if (!(cond)) { \
LOG("%s\n", (msg)); \
assert((cond)); \
} \
return(retval); \
} while(0)
My question is: is it possible to write a single RETURN_IF_FALSE macro to handle both void functions and functions returning a value? I sat down to attempt something using a varargs macro and quickly discovered I'm not very good at writing complex macros. I started out with this test program:
#include <stdio.h>
#include <assert.h>
#define RETURN_IF_FALSE(cond, msg, ... ) \
do { \
if (!(cond)) { \
fprintf(stderr, "%s\n", (msg)); \
assert((cond)); \
} \
return (##__VA_ARGS__); \
} while(0)
int main()
{
RETURN_IF_FALSE(1 < 0, "1 is not less than 0!", -1);
return 0;
}
Perhaps not surprisingly, it generated the following compile error:
g++ macro_test.cpp -o macro_test
macro_test.cpp:10:14: error: pasting "(" and "-" does not give a valid preprocessing token
return (##__VA_ARGS__); \
^
macro_test.cpp:16:5: note: in expansion of macro ‘RETURN_IF_FALSE’
RETURN_IF_FALSE(1 < 0, "1 is not less than 0!", -1);
^
Is it even possible to cover both cases with a single macro? I'm using gcc 4.8.1 on Linux. (I can compile with -std=c++11, if it helps...)
UPDATE: To bring this full-circle, here's the implementation I ultimately wound up with based on #Turix's answer and a suggestion from #Deduplicator to move the assert() call up to avoid a double evaluation of the conditional in the 'sunny day' case:
#define RETURN_IF_FALSE(cond, ... ) \
do { \
if (!(cond)) { \
const char* msg = \
"Pre-condition '" #cond "' not met, returning " #__VA_ARGS__ "..."; \
LOG("%s\n", msg); \
assert((cond)); \
return __VA_ARGS__; \
} \
} while(0)
(I decided it wasn't really all that necessary/useful to allow setting of a 'free form' message string, so I just generated a canned one from the condition...)
Just replace this part of your macro return (##__VA_ARGS__); with return __VA_ARGS__ ; and I think it should do what you want (assuming that what you would pass for the return value isn't a complex expression -- if it is, you would need to pre-wrap the parameter with parentheses).
I got this to work.
#include <stdio.h>
#define RET_IF_FALSE(x, y, z) if (!x) { printf(y); return z; }
int a(int *p)
{
RET_IF_FALSE(p, __FUNCTION__, 0);
return *p;
}
void b(int *p)
{
RET_IF_FALSE(p, __FUNCTION__, );
}
int main()
{
int x;
x = a(&x);
b(&x);
x = a(NULL);
b(NULL);
return 0;
}
It may not be the prettiest solution with a trailing comma, and it isn't compliant with standards according to gcc's -pedantic option.
Using:
#define RET_IF_FALSE(x, y, ...) if (!x) { printf(y); return __VA_ARGS__; }
with the rest of the code the same works for gcc with pedantic and -std=c99, and with -std=c++11 in clang++ and g++. Not sure what MS compilers do, as their support for standards is a little less stellar at times (and I haven't got a Windows setup to test on at present).

g++ __FUNCTION__ replace time

Can anyone tell when g++ replaces the __FUNCTION__ 'macro' with the string containing the function name? It seems it can replace it not until it has check the syntactical correctness of the source code, i.e. the following will not work
#include <whatsneeded>
#define DBG_WHEREAMI __FUNCTION__ __FILE__ __LINE__
int main(int argc, char* argv)
{
printf(DBG_WHEREAMI "\n"); //*
}
since after preprocessing using
g++ -E test.cc
the source looks like
[...]
int main(int argc, char* argv)
{
printf(__FUNCTION__ "test.cc" "6" "\n"); //*
}
and now the compiler rightly throws up because the *ed line is incorrect.
Is there any way to force that replacement with a string to an earlier step so that the line is correct?
Is __FUNCTION__ really replaced with a string after all? Or is it a variable in the compiled code?
Is there any way to force that replacement with a string to an earlier step so that the line is correct?
No. __FUNCTION__ (and its standardized counterpart, __func__) are compiler constructs. __FILE__ and __LINE__ on the other hand, are preprocessor constructs. There is no way to make __FUNCTION__ a preprocessor construct because the preprocessor has no knowledge of the C++ language. When a source file is being preprocessed, the preprocessor has absolutely no idea about which function it is looking at because it doesn't even have a concept of functions.
On the other hand, the preprocessor does know which file it is working on, and it also knows which line of the file it is looking at, so it is able to handle __FILE__ and __LINE__.
This is why __func__ is defined as being equivalent to a static local variable (i.e. a compiler construct); only the compiler can provide this functionality.
You are using __FUNCTION__ like a preprocessor macro, but it's a variable (please read http://gcc.gnu.org/onlinedocs/gcc/Function-Names.html).
Try printf("%s", __FUNCTION__) just for testing and it will print the function name.
__FUNCTION__ is not standard. Use __func__. As the documentation says, it's as if:
<ret-type> function_name( <args> )
{
static const char __func__[] = "function-name";
...
In C/C++, the preprocessor will turn "my " "name " "is " "Bob" into the string literal "my name is Bob"; since __FILE__ and __LINE__ are preprocessor instructions, "We are on line " __LINE__ will pass "We are on line 27" to the compiler.
__FUNCTION__ is normally a synonym for __func__. __func__ can be thought of as a pseudo-function that returns the name of the function in which it is called. This can only be done by the compiler and not by the preprocessor. Because __func__ is not evaluated by the preprocessor, you do not get automatic concatenation. So if you are using printf it must be done by printf("the function name is %s", __func__);
Is this what you want?
#include <stdio.h>
#define DBG_WHEREAMI(X) printf("%s %s(%d): %s\n",__func__,__FILE__,__LINE__,X)
int main(int argc, char* argv)
{
DBG_WHEREAMI("Starting");
}
Note: Since you marked this as C++ you should probably be using the iostreams to make sure it's type safe.
printf("%s" __FILE__ __LINE__ "\n", __FUNCTION__);
Yeah, I know that's not really the same.
Note that if you create a class, you can build a message from any number of types as you'd like which means you have a similar effect to the << operator or the format in a printf(3C). Something like this:
// make sure log remains copyable
class log
{
public:
log(const char *function, const char *filename, int line)
{
f_message << function << ":" << filename << ":" << line << ": ";
}
~log()
{
//printf("%s\n", f_message.str().c_str()); -- printf?!
std::cerr << f_message.str() << std::endl;
}
log& operator () (const char *value)
{
f_message << value;
}
log& operator () (int value)
{
f_message << value;
}
// repeat with all the types you want to support in the base class
// (should be all the basic types at least)
private:
sstream f_message;
};
// start the magic here
log log_error(const char *func, const char *file, int line)
{
log l(func, file, line);
return l;
}
// NOTE: No ';' at the end here!
#define LOG_DEBUG log_error(__func__, __FILE__, __LINE__)
// usage sample:
LOG_DEBUG("found ")(count)(" items");
Note that you could declare the << operators instead of the (). In that case the resulting usage would be something like this:
LOG_DEBUG << "found " << count << " items";
Depends which you prefer to use. I kind of like () because it protects your expressions automatically. i.e. if you want to output "count << 3" then you'd have to write:
LOG_DEBUG << "found " << (count << 3) << " items";