Related
My goal is to print the filenames and not relative path to the filename. I'm experimenting with it using the macro TRACE().
Since it's all in the same file, I'm simulating the filename as an input to TRACE(). So in real life, you could say the inputs are replaced with __FILE__.
Code:
#include <stdio.h>
#include <string.h>
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define __FILENAME__(x) TOSTRING(strrchr(x, '\\'))
#define TRACE(s, ...) \
{ \
if (strrchr(s, '\\')) { \
static const char str[] = __FILENAME__(s) "\n\r"; \
printf(str, ##__VA_ARGS__); \
} else { \
static const char str[] = s "\n\r"; \
printf(str, ##__VA_ARGS__); \
} \
}
int main() {
TRACE("file.c");
TRACE("parent\\file.c");
return 0;
}
Output:
file.c
strrchr("parent\\file.c", '\\')
So if it's local file, it's printed as file.c, which is great. This means the ifcase in the macro is working :). But when it's a file in another folder, I fail to "stringify" the computation strrchr(s, '\\'). Why?
Furthermore, I don't see an issue with the computation in the define, since everything is defined at compile time!! (That's why the if case is working, right?)
If I remove the TOSTRING() from __FILENAME__ I get loads of errors instead. Because it fails to concatenate the output of __FILENAME__ with str[]
Is there a way to solve this?
Preliminary observations
Note that in C (as opposed to C++), you can't initialize a static const char str[] array with the result of a function call. If the strrchr() found a backslash, you probably want to print the name from one after the backslash. And the stringification isn't going to stringify the result of invoking strrchr().
Also note that you should not create function or variable names that start with an underscore, in general. C11 §7.1.3 Reserved identifiers says (in part):
All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.
All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces.
See also What does double underscore (__const) mean in C?
Since the first argument to your TRACE macro is already a string, there's not much benefit to applying the stringification — unless you want the double quotes to appear when the name is printed.
Simple adaptation
To get more or less the result you want, you would need to accept that there'll be run-time overhead invoking strrchr() each time you pass the trace (or a more elaborate scheme for initialization), along the lines of:
#define TRACE(s, ...) \
do { \
const char *basename = strrchr(s, '\\'); \
if (basename == 0) \
basename = s; \
else \
basename++; \
printf(basename, ## __VA_ARGS__); \
} while (0)
The do { … } while (0) idiom is standard; it allows you to write:
if (something)
TRACE("hocuspocus.c: test passed\n");
else
TRACE("abracadabra.c: test failed\n");
If you use the braces-only notation in the question, the semicolon after the first TRACE makes the else into a syntax error. See also C #define macro for debug printing and Why use apparently meaningles do { … } while (0) and if … else statements in macros? and do { … } while (0) — what is it good for?
The ## __VA_ARGS__ trick is fine as long as you know that it is a GCC (and Clang because it is compatible with GCC) extension, and not a part of standard C.
It also isn't entirely clear how you plan to use the variable arguments. It looks as though you'd be able to do:
TRACE("some\\kibbitzer.c: value %d is out of the range [%d..%d]\n",
value, MIN_RANGE, MAX_RANGE);
where the file name is embedded in the format string. Maybe you have in mind:
TRACE(__FILE__ ": value %d is out of the range [%d..%d]\n",
value, MIN_RANGE, MAX_RANGE);
That can work; __FILE__ is a string literal, unlike __func__ which is a predefined identifier (static const char __func__[] = "…function name…";).
Finally (for now), consider whether trace output should go to standard output or to standard error. It is easily arguable it should go to standard error; it (probably) isn't part of the regular output of the program.
I recommend looking at the 'debug macro' question and answer — but I am biassed since I wrote the top-scoring answer.
Reducing runtime overhead
You can reduce the runtime overhead to a single call to strrchr() per file name, as long as you aren't messing with automatic variables etc. You'll be OK if you're using string literals.
#define TRACE(s, ...) \
do { \
static const char *basename = 0;
if (basename == 0) \
{
if ((basename = strrchr(s, '\\')) == 0) \
basename = s; \
else \
basename++; \
} \
printf(basename, ## __VA_ARGS__); \
} while (0)
This initializes the basename to null; on the first pass through the code, basename is set to the correct position in the string; thereafter, there is no further call to strrchr().
Warning: the code shown has not been compiled.
I think there is some issue with the understanding of how macros and functions work.
Macros are not "executed", they are just simple text substitution. Yes, that happens in the compile time (actually pre compiling), but just the substitution.
Macros won't execute and code or call any functions (like strrchr) while compiling.
In your code you have -
#define __FILENAME__(x) TOSTRING(strrchr(x, '\\'))
Whenever __FILENAME__(foo) is used, it is replaced with "strrchr(foo, '\\')". I am sure this is not what you want.
Personally, I don't see any reason for using macros here. Just make it into a normal function. The compiler will optimize it for you.
I'm developing an embedded application that uses a library for interfacing with a SPI NAND memory chip. The library provided uses a print function in which I, as the applications developer, must override for my specific platform.
For instance, they use the function printf_ extensively in their code.
I redefine it as such, to get the print function to print over the serial interface
#define printf_(...) serial.printf(__VA_ARGS__)
It works fine, except that on this platform, you need to supply a carriage return ("\r") for a newline. So right now, when the library is called, the formatting is horrible.
I'd like to append a "\r" to the end of whatever is supplied to the print function. Like
#define printf_(...) serial.printf(__VA_ARGS__##"\r")
Obviously that doesn't work.
I'm really not familiar with, and have sort of a hard time understanding variadic functions in C, so this would provide me with a little learning opportunity if I could figure this out, or at least I would learn if this is not possible.
I also can't just wrap the function using va_lists and vsprintfs because my platform does not support this (and I'd rather redefine it in a macro, as a performance/stylistic choice, personally).
Is there a way to do this?
Perhaps you could just output '\r' after the call to serial.printf ?
#define printf_(...) do { serial.printf(__VA_ARGS__); serial.printf("\r"); } while(0)
I agree with other users that your requirement of CR coming after LF is quite strange, and I have a strong suspicion you mean for it to be CRLF, not LFCR. Regardless, I will help you with your original requirement of appending CR to the string.
It is going to be incredibly difficult to perform this operation in a one-liner macro. Alternatively, you could use a nasty-looking multi-line macro:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define printf_(format, args...) \
do { \
int _len_orig = strlen(format); \
/* strlen doesn't consider newline. Check for that. */ \
if ( format[_len_orig] == '\n' ) \
_len_orig++; \
\
/* len_orig + 2 to make space for null terminator and '\r' */ \
unsigned _new_size = _len_orig + 2; \
char* _new_str = calloc(_new_size, 1); \
strncpy( _new_str, format, _len_orig ); \
_new_str[_new_size-2] = '\r'; \
\
/* Print out the raw hex of the string to prove it worked */ \
int _i; \
for( _i = 0; _i < _new_size; _i++) \
printf("%02x ", _new_str[_i]); \
printf("\n"); \
free(_new_str); \
} while(0)
int main(){
char* str = "####\n";
printf_( str );
return 0;
}
In my macro, I have not used your serial.printf function but rather made some short code that prints out the hexidecimal values of the concatenated string for proof that the logic works.
Explanation
Macros are required to appear as a single line to the C Preprocessor. The additions of \ at the end of each macro line escape the newline character.
gcc allows for named arguments in your macro. Here, format describes the format string you would normally pass to printf, and args... is the variable argument name for "everything else" you would pass into printf. I do not reference args in this example, but you will certainly want to modify my example in your final code to include it. Your call to printf would look something like serial.printf( _new_str, args);
Multi-line macros are kind of nasty in that you need to do some trickery to get them to appear as normal functions to the human programmer. The need for enclosing the macro in a do-while is nicely discussed here. The linked page is meant for C++, but it applies to C as well.
If you copy my code, compile, and run it, this is the output:
[clipp#h2ologin3:~]$ ./a.out
40 40 40 40 0a 0d 00
Here, this ASCII dump is showing us that 4 # symbols were copied, followed by \n, \r, and finally \0.
There is also a strong case for instead writing this as an inline C function. You say that your system doesn't support va_list etc. so if that is true, then a macro may be the only choice.
QED.
I have a lot of lines of code like below:
sp_setup_point( setup, get_vert(vertex_buffer, i-0, stride) );
for each of them, I want to be able to extract (i-0) and pass it to another function. like:
sp_setup_point( setup, get_vert(vertex_buffer, i-0, stride) );
my_test_func(i-0);
so I wrote two macro:
#define GET_VERT(_x, _y, _z) get_vert(_x, _y, _z) , _y
#define SP_SETUP_POINT(_x, _y, _z) sp_setup_point(_x, _y); my_test_func(_z);
and call them like:
SP_SETUP_POINT( setup, GET_VERT(vertex_buffer, i-0, stride));
however, it does not give what I want, it expands to:
sp_setup_point(setup, get_vert(vertex_buffer, i-0, stride), i-0); my_test_func();
and MSVC compiler complains
not enough actual parameters for macro 'SP_SETUP_POINT'
I searched quite a bit, according to https://gcc.gnu.org/onlinedocs/cpp/Argument-Prescan.html
Macro arguments are completely macro-expanded before they are substituted into a macro body, unless they are stringified or pasted with other tokens. After substitution, the entire macro body, including the substituted arguments, is scanned again for macros to be expanded. The result is that the arguments are scanned twice to expand macro calls in them
the argument are fully expanded, but the additional argument is not recognized. how it that ? any suggestion is appreciated.
The reason, IIRC, is that GET_VERT inside of an actual parameter list gets only expanded after the enclosing macro call is scanned. So the PP first wants to see the ")" at the end of the parameter list of SP_SETUP_POINT. In this process it recognizes that it is one parameter short of the declared form. One level of indirection helps, but beware, macro programming in C is strange and suffers from early bad implementation choices that no one ever dared to correct due to massive compatibility debt.
#define GET_VERT(_x, _y, _z) get_vert(_x, _y, _z) , _y
#define SP_SETUP_POINT(_x, expandme) SP_SETUP_POINT_(_x,expandme)
#define SP_SETUP_POINT_(_x,_y,_z) sp_setup_point(_x, _y); my_test_func(_z)
The last form is better written as
#define SP_SETUP_POINT_(_x,_y,_z) do{ sp_setup_point(_x, _y); my_test_func(_z); }while(0)
because writing sg. like
if (a==1) SP_SETUP_POINT(setup, GET_VERT(vertex_buffer, i-0, stride));
will lead to invisible errors in the control flow.
If I was going to tackle this, I think I'd start from the desired output:
sp_setup_point( setup, get_vert(vertex_buffer, i-0, stride) );
my_test_func(i-0);
You have 4 parameters: setup, vertex_buffer, expr, and stride, where expr is the i-0 parameter (which is itself a peculiar notation; how does that differ from i?). I might use those longer names in production-quality macros; I'm going to use short names a .. d here.
So, I'd design my macro from that starting point:
#define SP_SETUP_POINT(a, b, c, d) \
do { sp_setup_point((a), get_vert((b), (c), (d))); \
my_test_func(c); } while (0)
You could then invoke:
SP_SETUP_POINT(setup, vertex_buffer, i-0, stride);
This would generate the code you desire, even in a context such as:
if (x > y)
SP_SETUP_POINT(setup, vertex_buffer, i-0, stride);
else
SP_SETUP_POINT(setup, vertex_buffer, i+2, stride);
If you don't use the do { … } while (0) notation, then you have to use a comma operator to separate the function calls:
#define SP_SETUP_POINT(a, b, c, d) \
(sp_setup_point((a), get_vert((b), (c), (d))), \
my_test_func(c))
This evaluates to the return value from my_test_func(). There's no problem if you don't need to test the return value from sp_setup_point() — e.g. if it returns void anyway — and there's no problem if my_test_func() returns void.
You can also modify the macro to call MY_TEST_FUNC(c) and then conditionally define it:
#ifdef CALL_MY_TEST_FUNCTION
#define MY_TEST_FUNC(c) my_test_func(c)
#else
#define MY_TEST_FUNC(c) ((void)(c))
#endif
The advantage of evaluating c in the 'do not call' case is that the compiler ensures that c remains valid even as the code changes. Do not under-estimate the benefit of that in long-lived code.
I have the following macro function in vanilla C:
#define GLOG(format_string, ...) { \
const char *file = strrchr(__FILE__, '/'); \
char format[256] = "%s:%s!%d\t"; \
strncat(format, format_string, 248); \
strcat(format, "\n"); \
printf(format, __FUNCTION__, file ? file : __FILE__, __LINE__, ##__VA_ARGS__); \
}
which lets me print a debug message containing the current function, file and line number, e.g.
GLOG("count=%d", count);
might print
do_count:counter.c!123 count=456
How can I modify the function to print all local variables if caller omits format_string? e.g.
GLOG();
might print
do_count:counter.c!123 count=456, message="Hello world", array=[7, 8] structure={ptr=0xACE0FBA5E, coord={x=9, y=0}}
If that's not possible, how can I modify it to print just the current function, file and line number? e.g.
do_count:counter.c!123
As is, this returns an error:
error: expected expression before ‘,’ token
as the strncat line is simply
strncat(format, , 248);
First, inspecting all the local variables at runtime by the process itself seems impossible because C doesn't have any means for reflection.
Second, you would be much better off if you wrote the logging macro like that:
#include <stdio.h>
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define GLOGF(fmt, ...) \
printf("%s:%s " fmt "\n", __func__, __FILE__ "!" TOSTRING(__LINE__), ##__VA_ARGS__)
int main (void) {
/* main:test.c!xx count=5 */
GLOGF("count=%d", 5);
/* main:test.c!xx */
GLOGF();
return 0;
}
It is simpler and doesn't incur any additional runtime overhead since the string is concatenated at compile-time.
Also note that I have used __func__ instead of __FUNCTION__, because the latter is non-standard.
I found this link in this answer. It might help you with the first part of the question.
The second, how to get all local variables, is much harder, if not impossible. The reason is that the code, when compiled, doesn't actually have variables, it just have offsets into a memory area (the stack.) It might be possible that your compiler have internal functions that can be used to inspect the stack, but then you only have possible values not the names of the variables. The only solution I see it to use special pre-processor macros to declare local variables, and then a list of structures to represent them for introspection, which will be a lot of both runtime and memory overhead.
As others here have mentioned, C does not have reflection features, and therefore you are not going to be capable of capturing the local variables in a macro call. That being said, if you want something to conditionally happen with a macro depending on if there are or are not any arguments to the macro invocation (i.e., your "non-null" and "null" arguments), then you can do something like the following:
#include <string.h>
#define NULL_IDENT ""
#define IDENT(ident_name) #ident_name
#define MACRO(ident_name) \
if (strcmp(NULL_IDENT, IDENT(ident_name)) == 0) { \
/* add code for a null argument passed to the macro */ } \
else { \
/* add code for a non-null argument passed to the macro */ }
Based on Blagovest Buyukliev's answer, I've come up with the following solution for part 2:
#define GLOG(fmt, ...) do { const char *fn = strrchr(__FILE__, '/'); \
printf("%s:%s!%d\t"fmt"\n",__func__,fn?++fn:__FILE__,__LINE__,##__VA_ARGS__);\
} while(0)
using the preprocessor's string concatenation to simply concatenate a null string if the parameter is omitted.
Additionally, I added the do {...} while(0) to swallow the trailing semicolon so that the following if...else works:
if (...)
GLOG();
else
/* do something else */
(idea from http://gcc.gnu.org/onlinedocs/cpp/Swallowing-the-Semicolon.html ).
As mentioned in many of my previous questions, I'm working through K&R, and am currently into the preprocessor. One of the more interesting things — something I never knew before from any of my prior attempts to learn C — is the ## preprocessor operator. According to K&R:
The preprocessor operator ##
provides a way to concatenate actual
arguments during macro expansion. If a
parameter in the replacement text is
adjacent to a ##, the parameter is
replaced by the actual argument, the
## and surrounding white space are
removed, and the result is re-scanned.
For example, the macro paste
concatenates its two arguments:
#define paste(front, back) front ## back
so paste(name, 1) creates the token
name1.
How and why would someone use this in the real world? What are practical examples of its use, and are there gotchas to consider?
One thing to be aware of when you're using the token-paste ('##') or stringizing ('#') preprocessing operators is that you have to use an extra level of indirection for them to work properly in all cases.
If you don't do this and the items passed to the token-pasting operator are macros themselves, you'll get results that are probably not what you want:
#include <stdio.h>
#define STRINGIFY2( x) #x
#define STRINGIFY(x) STRINGIFY2(x)
#define PASTE2( a, b) a##b
#define PASTE( a, b) PASTE2( a, b)
#define BAD_PASTE(x,y) x##y
#define BAD_STRINGIFY(x) #x
#define SOME_MACRO function_name
int main()
{
printf( "buggy results:\n");
printf( "%s\n", STRINGIFY( BAD_PASTE( SOME_MACRO, __LINE__)));
printf( "%s\n", BAD_STRINGIFY( BAD_PASTE( SOME_MACRO, __LINE__)));
printf( "%s\n", BAD_STRINGIFY( PASTE( SOME_MACRO, __LINE__)));
printf( "\n" "desired result:\n");
printf( "%s\n", STRINGIFY( PASTE( SOME_MACRO, __LINE__)));
}
The output:
buggy results:
SOME_MACRO__LINE__
BAD_PASTE( SOME_MACRO, __LINE__)
PASTE( SOME_MACRO, __LINE__)
desired result:
function_name21
CrashRpt: Using ## to convert macro multi-byte strings to Unicode
An interesting usage in CrashRpt (crash reporting library) is the following:
#define WIDEN2(x) L ## x
#define WIDEN(x) WIDEN2(x)
//Note you need a WIDEN2 so that __DATE__ will evaluate first.
Here they want to use a two-byte string instead of a one-byte-per-char string. This probably looks like it is really pointless, but they do it for a good reason.
std::wstring BuildDate = std::wstring(WIDEN(__DATE__)) + L" " + WIDEN(__TIME__);
They use it with another macro that returns a string with the date and time.
Putting L next to a __ DATE __ would give you a compiling error.
Windows: Using ## for generic Unicode or multi-byte strings
Windows uses something like the following:
#ifdef _UNICODE
#define _T(x) L ## x
#else
#define _T(x) x
#endif
And _T is used everywhere in code
Various libraries, using for clean accessor and modifier names:
I've also seen it used in code to define accessors and modifiers:
#define MYLIB_ACCESSOR(name) (Get##name)
#define MYLIB_MODIFIER(name) (Set##name)
Likewise you can use this same method for any other types of clever name creation.
Various libraries, using it to make several variable declarations at once:
#define CREATE_3_VARS(name) name##1, name##2, name##3
int CREATE_3_VARS(myInts);
myInts1 = 13;
myInts2 = 19;
myInts3 = 77;
Here's a gotcha that I ran into when upgrading to a new version of a compiler:
Unnecessary use of the token-pasting operator (##) is non-portable and may generate undesired whitespace, warnings, or errors.
When the result of the token-pasting operator is not a valid preprocessor token, the token-pasting operator is unnecessary and possibly harmful.
For example, one might try to build string literals at compile time using the token-pasting operator:
#define STRINGIFY(x) #x
#define PLUS(a, b) STRINGIFY(a##+##b)
#define NS(a, b) STRINGIFY(a##::##b)
printf("%s %s\n", PLUS(1,2), NS(std,vector));
On some compilers, this will output the expected result:
1+2 std::vector
On other compilers, this will include undesired whitespace:
1 + 2 std :: vector
Fairly modern versions of GCC (>=3.3 or so) will fail to compile this code:
foo.cpp:16:1: pasting "1" and "+" does not give a valid preprocessing token
foo.cpp:16:1: pasting "+" and "2" does not give a valid preprocessing token
foo.cpp:16:1: pasting "std" and "::" does not give a valid preprocessing token
foo.cpp:16:1: pasting "::" and "vector" does not give a valid preprocessing token
The solution is to omit the token-pasting operator when concatenating preprocessor tokens to C/C++ operators:
#define STRINGIFY(x) #x
#define PLUS(a, b) STRINGIFY(a+b)
#define NS(a, b) STRINGIFY(a::b)
printf("%s %s\n", PLUS(1,2), NS(std,vector));
The GCC CPP documentation chapter on concatenation has more useful information on the token-pasting operator.
This is useful in all kinds of situations in order not to repeat yourself needlessly. The following is an example from the Emacs source code. We would like to load a number of functions from a library. The function "foo" should be assigned to fn_foo, and so on. We define the following macro:
#define LOAD_IMGLIB_FN(lib,func) { \
fn_##func = (void *) GetProcAddress (lib, #func); \
if (!fn_##func) return 0; \
}
We can then use it:
LOAD_IMGLIB_FN (library, XpmFreeAttributes);
LOAD_IMGLIB_FN (library, XpmCreateImageFromBuffer);
LOAD_IMGLIB_FN (library, XpmReadFileToImage);
LOAD_IMGLIB_FN (library, XImageFree);
The benefit is not having to write both fn_XpmFreeAttributes and "XpmFreeAttributes" (and risk misspelling one of them).
A previous question on Stack Overflow asked for a smooth method of generating string representations for enumeration constants without a lot of error-prone retyping.
Link
My answer to that question showed how applying little preprocessor magic lets you define your enumeration like this (for example) ...;
ENUM_BEGIN( Color )
ENUM(RED),
ENUM(GREEN),
ENUM(BLUE)
ENUM_END( Color )
... With the benefit that the macro expansion not only defines the enumeration (in a .h file), it also defines a matching array of strings (in a .c file);
const char *ColorStringTable[] =
{
"RED",
"GREEN",
"BLUE"
};
The name of the string table comes from pasting the macro parameter (i.e. Color) to StringTable using the ## operator. Applications (tricks?) like this are where the # and ## operators are invaluable.
You can use token pasting when you need to concatenate macro parameters with something else.
It can be used for templates:
#define LINKED_LIST(A) struct list##_##A {\
A value; \
struct list##_##A *next; \
};
In this case LINKED_LIST(int) would give you
struct list_int {
int value;
struct list_int *next;
};
Similarly you can write a function template for list traversal.
The main use is when you have a naming convention and you want your macro to take advantage of that naming convention. Perhaps you have several families of methods: image_create(), image_activate(), and image_release() also file_create(), file_activate(), file_release(), and mobile_create(), mobile_activate() and mobile_release().
You could write a macro for handling object lifecycle:
#define LIFECYCLE(name, func) (struct name x = name##_create(); name##_activate(x); func(x); name##_release())
Of course, a sort of "minimal version of objects" is not the only sort of naming convention this applies to -- nearly the vast majority of naming conventions make use of a common sub-string to form the names. It could me function names (as above), or field names, variable names, or most anything else.
I use it in C programs to help correctly enforce the prototypes for a set of methods that must conform to some sort of calling convention. In a way, this can be used for poor man's object orientation in straight C:
SCREEN_HANDLER( activeCall )
expands to something like this:
STATUS activeCall_constructor( HANDLE *pInst )
STATUS activeCall_eventHandler( HANDLE *pInst, TOKEN *pEvent );
STATUS activeCall_destructor( HANDLE *pInst );
This enforces correct parameterization for all "derived" objects when you do:
SCREEN_HANDLER( activeCall )
SCREEN_HANDLER( ringingCall )
SCREEN_HANDLER( heldCall )
the above in your header files, etc. It is also useful for maintenance if you even happen to want to change the definitions and/or add methods to the "objects".
SGlib uses ## to basically fudge templates in C. Because there's no function overloading, ## is used to glue the type name into the names of the generated functions. If I had a list type called list_t, then I would get functions named like sglib_list_t_concat, and so on.
I use it for a home rolled assert on a non-standard C compiler for embedded:
#define ASSERT(exp) if(!(exp)){ \
print_to_rs232("Assert failed: " ## #exp );\
while(1){} //Let the watchdog kill us
I use it for adding custom prefixes to variables defined by macros. So something like:
UNITTEST(test_name)
expands to:
void __testframework_test_name ()
One important use in WinCE:
#define BITFMASK(bit_position) (((1U << (bit_position ## _WIDTH)) - 1) << (bit_position ## _LEFTSHIFT))
While defining register bit description we do following:
#define ADDR_LEFTSHIFT 0
#define ADDR_WIDTH 7
And while using BITFMASK, simply use:
BITFMASK(ADDR)
It is very useful for logging. You can do:
#define LOG(msg) log_msg(__function__, ## msg)
Or, if your compiler doesn't support function and func:
#define LOG(msg) log_msg(__file__, __line__, ## msg)
The above "functions" logs message and shows exactly which function logged a message.
My C++ syntax might be not quite correct.