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
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__);
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";
...
printf("%s" __FILE__ __LINE__ "\n", __FUNCTION__);
Yeah, I know that's not really the same.
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.
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";