I want to implement a function tracer, which would trace how much time a function is taking to execute. I have following class for the same:-
class FuncTrace
VC++ has
__FUNCTION__ for undecorated names
and
__FUNCDNAME__ for decorated names
And you can write a macro that will itself allocate an object and pass the name-yelding macro inside the constructor. Smth like
#define ALLOC_LOGGER FuncTracer ____tracer( __FUNCTION__ );
I was going to say I didn't know of any such thing but then I saw the other answers...
It might interest you to know that an execution profiler (like gprof
) does exactly what you're asking about - it tracks the amount of time spent executing each function. A profiler basically works by recording the instruction pointer (IP), the address of the currently executing instruction, every 10ms or so. After the program is done running, you invoke a postprocessor that examines the list of IPs and the program, and converts those addresses into function names. So I'd suggest just using the instruction pointer, rather than the function name, both because it's easier to code and because it's more efficient to work with a single number than with a string.
C++20 std::source_location::function_name
This does basically exactly what you want.
https://en.cppreference.com/w/cpp/utility/source_location claims usage will be like:
#include <iostream>
#include <string_view>
#include <source_location>
void log(std::string_view message,
const std::source_location& location std::source_location::current()
) {
std::cout << "info:"
<< location.file_name() << ":"
<< location.line() << ":"
<< location.function_name() << " "
<< message << '\n';
}
int main() {
log("Hello world!");
}
Possible output:
info:main.cpp:16:main Hello world!
so note how the call preserves caller information.
I have covered the relevant standards in a bit more detail at: What's the difference between __PRETTY_FUNCTION__, __FUNCTION__, __func__?
C99 has __func__
, but for C++ this will be compiler specific. On the plus side, some of the compiler-specific versions provide additional type information, which is particularly nice when you're tracing inside a templatized function/class.
__FUNCTION__
, __FUNCDNAME__
, __FUNCSIG__
__func__
, __FUNCTION__
, __PRETTY_FUNCTION__
Boost library has defined macro BOOST_CURRENT_FUNCTION
for most C++ compilers in header boost/current_function.hpp. If the compiler is too old to support this, the result will be "(unknown)".