what I'd like to do (for logging purposes) is something like this:
This code has been written to show my problem, actual code is complex and yes, I have good reasons to use macros even on C++ =)
# define LIB_SOME 1
# define LIB_OTHER 2
# define WHERE "at file #a, line #l, function #f: "
// (look for syntax hightlighting error at SO xd)
# define LOG_ERROR_SIMPLE(ptr, lib, str) ptr->log ("ERROR " str \
" at library " #lib);
# define LOG_ERROR(ptr, lib, str) LOG_ERROR_SIMPLE(ptr, lib, WHERE str)
LOG_ERROR_SIMPLE (this, LIB_SOME, "doing something")
LOG_ERROR (this, LIB_OTHER, "doing something else")
LOG_ERROR_SIMPLE()
writes the stringification of the lib parameter (a macro name surrounded by " ")
but then LOG_ERROR
writes the stringification of the macro already expanded ("2"). this is expected, since lib got its expansion before expanding and calling LOG_ERROR_SIMPLE
. but this is not what I need.
Basically my question is this: how to avoid macro expansion of a macro function parameter when calling another macro function?
There is a trick I use that avoids macro expansion:
LOG_ERROR(ptr, lib, str, x) LOG_ERROR_SIMPLE(ptr, x##lib, WHERE str)
LOG_ERROR(this, LIB_OTHER, "some error",)
(pasting x and lib produces LIB_OTHER
and this value is used to call LOG_ERROR_SIMPLE
, its not macro expanded before that call)
There is some way to obtain this same behaviour without using a trick?
I'm doing:
#include <cstdio>
#define FOO 1
#define BAR 2
#define LOG_SIMPLE(ptr, lib, str) printf("%s\n", #lib);
#define LOG(ptr, lib, str) LOG_SIMPLE(ptr, ##lib, str)
int main()
{
LOG_SIMPLE(0, FOO, "some error");
LOG(0, BAR, "some other error");
}
which prints out:
FOO
BAR
Works with MSVC2005 but not with gcc/g++.
EDIT: to make it work with gcc/g++ you can abuse variadic macros:
#include <stdio.h>
#define FOO 1
#define BAR 2
#define LOG_SIMPLE(ptr, str, lib) printf("%s\n", #lib);
#define LOG(ptr, str, lib, ...) LOG_SIMPLE(ptr, str, lib##__VA_ARGS__)
int main()
{
LOG_SIMPLE(0, "some error", FOO);
LOG(0, "some other error", BAR);
LOG(0, "some other error", FOO, BAR);
}
However, it's your discipline not to use the macro with too many parameters. MSVC2005 prints out
FOO
BAR
FOO2
while gcc prints out
FOO
BAR
FOOBAR
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With