Reputation: 11
I've just found something as get the name of current function or get name of the caller, some variants to get or call the name as string.
What I want is to get the name of the function that I passed in arguments. Like this:
void Bar()
{
//do something
}
void Foo(void (*f)())
{
//this will output: Foo
std::cout << __FUNCTION__ << std::endl;
//How do I get the name passed to f? (in this case: Bar)
}
int main()
{
Foo(Bar);
return 0;
}
Thanks.
Edit: Here is an extremely near code for what I'm trying following the suggestion of @Jose.
thread_local const char * m_last_function_called = "";
#define register_function() {m_last_function_called = __FUNCTION__;}
inline const char * get_last_function() { return m_last_function_called; }
// const char * g_last_function_called = "";
// #define register_function() { g_last_function_called = __FUNCTION__; }
// inline const char * get_last_function() { return g_last_function_called; }
void print_last_func()
{
static std::mutex sync_cout;
std::lock_guard<std::mutex> l(sync_cout);
std::cout << get_last_function() << std::endl;
}
bool interruptFooTimer = false;
int FooTimer()
{
register_function();
print_last_func();
std::cout << "FooTimer.start" << std::endl;
int t = 0;
while(t<10)
{
if(interruptFooTimer==false)
{
sleep(1);
t++;
std::cout << "\tt=" << t << std::endl;
}
else
{
return -1;
}
}
std::cout << "FooTimer.end" << std::endl;
return 0;
}
void CallTrd(int (*f)())
{
std::thread TrdTemp(f);
TrdTemp.detach();
TrdTemp.~thread();
print_last_func();
}
int main()
{
CallTrd(FooTimer);
print_last_func();
int c = 0;
while(c<15)
{
if(c==7) {interruptFooTimer=true;}
sleep(1);
c++;
std::cout << "c=" << c << std::endl;
print_last_func();
}
return 0;
}
Observe that I call print_last_func() in different moments and all get the same value that was initialized in the variable. This sample code calls a thread without using join() because I can't wait for the thread to finish and also implement the detach() and ~thread to finish my program without any exception. The interruptFooTimer I'm using to safely "terminate" my thread. What am I missing to get global the value acquired in register_function??
Upvotes: 1
Views: 3328
Reputation: 3527
I don't know why you wanna do it, but I hope it's for debugging purpose. Obviously the easiest path is to pass the __FUNCTION__
as an argument as pointed out. But in my point of view, there's a better approach.
You could have for example, a global variable:
thread_local const char * g_last_function_called = "";
#define register_function() { g_last_function_called = __FUNCTION__; }
inline const char * get_last_function() { return g_last_function_called; }
void Bar()
{
register_function()
}
void Foo(void (*f)())
{
std::cout << get_last_function() << std::endl;
}
void my_func_that_doesnt_accept_nulls(CClass * p)
{
if (p == nullptr)
{
std::cout << " function" << get_last_function();
std::cout << "passed a bad pointer, fix it" << std::endl;
return;
}
}
Of course, this will not give you the right result in multi-thread, but you can probably fix that using a thread_local const char * g_last_function_called = ""
variable.
The reason why I like this method is because all you have to do to remove it from your project is just a simple "find and replace" of register_function(), and since it uses plain pointers, there's no way it can slow your program at all.
Edit: this is how I'm testing the code
void print_last_func()
{
static std::mutex sync_cout;
std::lock_guard<std::mutex> l(sync_cout);
std::cout << get_last_function() << std::endl;
}
void HelloWorld1()
{
register_function();
print_last_func();
}
void HelloWorld2()
{
register_function();
print_last_func();
}
int main()
{
register_function();
std::thread t1(HelloWorld1);
std::thread t2(HelloWorld2);
print_last_func();
t1.join();
t2.join();
return 0;
}
I get: HelloWorld1, HelloWorld2, and main
Upvotes: 0
Reputation: 2124
As others have already noted, you cannot do this directly.
First of all I would use std::function instead of a raw function pointer and std::string to hold the function's name.
I would also wrap these up like this:
template<class T>
struct Functor
{
std::function<T> functor_;
std::string name_;
Functor(const std::function<T>& functor, const std::string& name)
: functor_(functor)
, name_(name)
{}
};
You can then use it like so:
void Bar()
{
// do something
}
void Foo(const Functor<void()>& functor)
{
}
int main()
{
Functor<void()> f(std::bind(Bar), "Bar");
Foo(f);
return 0;
}
You can also use a macro to make things easier for you.
#define FUNCTOR(t, x, ...) Functor<t>(std::bind(&x, __VA_ARGS__), #x)
Which can be used like this:
int main()
{
auto f = FUNCTOR(void(), Bar);
return 0;
}
Note that if you take this approach that the function name might not be the same as what using __FUNCTION__
yields.
Upvotes: 0
Reputation: 69
Use a helper macro:
#define Foo(x) FooHelper(#x, x)
void FooHelper(const char *f_name, void (*f)())
{
cout << f_name;
}
Upvotes: 0
Reputation: 18825
You cannot. __FUNCTION__
is expanded by compiler during the compilation time. You cannot get this information in runtime.
Upvotes: 1