CPP: avoiding macro expansion of a macro function parameter - c++

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 don't need the expanded lib aliases (i.e. '1' & '2') in your cpp macros, you could also use an enum instead of defined values.

I don't think you can. What you could do, though, is add a layer of macro for it to unpeel in its place:
#define WRAP(x) x
#define LOG_ERROR(ptr, lib, str) LOG_ERROR_SIMPLE(ptr, lib, WHERE WRAP(str))

You almost had it. Use
#define LOG_ERROR(ptr, lib, str) LOG_ERROR_SIMPLE(ptr, ##lib, WHERE str)
On gcc
LOG_ERROR(this, LIB_OTHER, "some error")
yields
this->log ("ERROR " "at file #a, line #l, function #f: " "some error" " at library " "LIB_OTHER");
I would also remove the trailing ';' from your macro so that your code would look like:
LOG_ERROR(this, LIB_OTHER, "some error");

Related

How to redefine a C++ #define macro using information from the macro itself?

Is it possible to redefine a C++ #define macro using information from the macro itself? I tried the code below, but because of the way the macros are evaluated the output was not what I expected.
#include <iostream>
#define FINAL_DEFINE "ABC"
#define NEW_DEFINE FINAL_DEFINE "DEF" // Want ABCDEF
#undef FINAL_DEFINE
#define FINAL_DEFINE NEW_DEFINE // Want ABCDEF, but get empty?
int main ()
{
std::cout << FINAL_DEFINE << std::endl; // Want ABCDEF, but doesn't compile.
}
Macros in macro bodies are never expanded when the macro is defined -- only when the macro is used. That means that the definition of NEW_DEFINE is not "ABC" "DEF", it is exactly what appears on the #define line: FINAL_DEFINE "DEF".
So when you use FINAL_DEFINE, that gets expanded to NEW_DEFINE which then gets expanded to FINAL_DEFINE "DEF". At this point it will not recursively expand FINAL_DEFINE (as that would lead to an infinite loop) so no more expansion occurs.
If your compiler supports push_macro & pop_macro pragma directives, you could do this:
#include <iostream>
#define FINAL_DEFINE "ABC"
#define NEW_DEFINE FINAL_DEFINE "DEF"
int main ()
{
std::cout << FINAL_DEFINE << std::endl; // Output ABC
#pragma push_macro("FINAL_DEFINE")
#define FINAL_DEFINE "XXX"
std::cout << NEW_DEFINE << std::endl; // Output XXXDEF
#pragma pop_macro("FINAL_DEFINE")
}
After preprocessing all FINAL_DEFINE in the code will be replaced with the last thing it defined and then going to compiling step.
So you cannot redefine the macro like you want.
Your compiler should warn you about that.

Convert a macro argument into a string constant and take into account commas

Say I have a C macro-defined product version like this:
#define FOO_VERSION 1,0,0,1
And I want to print it at run-time:
#define STRING_VALUE(x) #x
int main()
{
std::cout << STRING_VALUE(FOO_VERSION) << std::endl;
}
This will output a string "FOO_VERSION", not "1,0,0,1". The macro
argument 'FOO_VERSION' is not replaced. So I try it again like
this:
#define STRING_VALUE(x) STRING_VALUE__(x)
#define STRING_VALUE__(x) #x
int main()
{
std::cout << STRING_VALUE(FOO_VERSION) << std::endl;
}
It works, in Visual C++ 2013.
This is a cross-platform application although there are only five
lines of code. When I use clang to compile the code, a compile-
time error appears: "too many arguments provided to function-like
macro invocation". I guess the reason is the comma defined in
'FOO_VERSION'. So the third version:
#define STRING_VALUE(x) STRING_VALUE__(x)
#define STRING_VALUE__(a, b, c, d) #a "," #b "," #c "," #d
int main()
{
std::cout << STRING_VALUE(FOO_VERSION) << std::endl;
}
This code works in clang, but Visual C++ will output a warning:
"not enough actual parameters for macro 'STRING_VALUE__'" at
compile-time, of course the run-time output is not right.
My question: is this pre-processor behavior defined ? Can I have a
universal version of STRING_VALUE macro ?
You can treat the argument as a single variadic macro:
#define FOO_VERSION 1,0,0,1
#define STRING_VALUE(...) STRING_VALUE__(__VA_ARGS__)
#define STRING_VALUE__(...) #__VA_ARGS__
This seems to work with gcc and Visual C++.

Where are default parameters evaluated in c++?

If there is a function like the following,
void logData(std::string data, int line=__LINE__);
is the default parameter evaluated where the function is called, or where it is declared? Is the behavior standard, or does it depend on the compiler?
You asked:
is the default parameter evaluated where the function is called, or where it is declared? Is the behavior standard, or does it depend on the compiler?
The value of the default parameter will be the line number of the file where the function is declared. That is as per the standard.
From the C++11 Standard:
16.8 Predefined macro names
...
_ _ LINE _ _
The presumed line number (within the current source file) of the current source line (an integer constant).
Since __LINE__ is a pre-processor macro, the code being compiled by the compiler does not have __LINE__ in it. In its place, it will see an integer constant that represents the line number of the line in the file, which is the file where the function is declared.
This sounds like a question a Python programmer might ask but you've picked a variant that has two answers.
The first part is __LINE__ which is a pre-processor macro. Pre-processing is, as the name suggests, done before some "processing" step. In this case, it happens before the compiler tries to compile the code. pre-processing involves replacing "#include" statements with the pre-processed contents of the file, evaluating and replacing macros, #define and #if statements etc.
So when the compiler sees
void logData(... __LINE__)
on line 123 of a file, the __LINE__ is replaced with the constants 123. You can avoid this by using macros, e.g.
enum Level { DEBUG, NOTE, WARNING, ERROR };
#define FLD __FILE__, __LINE__, DEBUG
#define FLN __FILE__, __LINE__, NOTE
#define FLW __FILE__, __LINE__, WARNING
#define FLE __FILE__, __LINE__, ERROR
void log(const char* file_, size_t line_, Level level_, const char* what);
...
logData(FLD, "debug message");
As to where the arguments are "evaluated", call site; so you will not run into Python's
from __future__ import print_function
def f(inlist, l=[]):
if l:
l.append("unexpected surprise")
l.extend(inlist)
return l
f([1])
print(f([2]))
http://ideone.com/GvmsL6
[1, 'unexpected surprise', 2]
in c++
#include <iostream>
#include <vector>
#include <string>
using strvec = std::vector<std::string>;
strvec f(strvec in, strvec out={})
{
if (!out.empty())
out.push_back("unexpected surprise");
out.insert(out.end(), in.cbegin(), in.cend());
return out;
}
int main()
{
f({"a"});
auto vec = f({"b"});
for (auto& str: vec) {
std::cout << str << "\n";
}
}
See http://ideone.com/17ilNL

How to print macro name in c or c++

How to print macro name in c or c++
eg:
#define APINAME abc
#define PRINTAPI(x) printf("x")
I want to print PRINTAPI(APINAME) and not "abc"
Macros are pre-processors and they will be replaced by their associated statement before compiling the code. So, you have no chance to have the macro names in run-time. But, you can generate the string name in compile-time:
#define APINAME abc
#define PRINTAPI(x) std::cout << #x << std::endl;
int main()
{
PRINTAPI(APINAME);
}
Output
APINAME
In macros the operator # makes the input parameter to a string literal (stringify)
Since macros disappear when the preprocessor is doing it's work, which happens before the compiler is called, the APINAME will not exist anywhere in the source code for the compiler to deal with. The only solution is to come up with some sort of connection between the two in some other way, e.g.
struct foo{
const char *name;
const char *val;
} myvar = { "APINAME", APINAME };
With a macro, you can do this in as a one-liner:
#define APINAME "abc"
#define APINAME_VAR(x, y) struct foo x = { #y, y }
APINAME_VAR(myvar, APINAME)
or
cout << "APINAME=" << APINAME << endl
printf("APINAME=%s\n", APINAME);
Or, in the case of your macro:
#define PRINTAPI printf("%s=%s\n", #APINAME, APINAME)
will print APINAME=abc

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__))