Is there a way to get function name inside a C++ function? - c++

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 FuncTracer
{
public:
FuncTracer(LPCTSTR strFuncName_in)
{
m_strFuncName[0] = _T('\0');
if( strFuncName_in ||
_T('\0') != strFuncName_in[0])
{
_tcscpy(m_strFuncName,strFuncName_in);
TCHAR strLog[MAX_PATH];
_stprintf(strLog,_T("Entering Func:- <%s>"),m_strFuncName);
LOG(strLog)
m_dwEnterTime = GetTickCount();
}
}
~FuncTracer()
{
TCHAR strLog[MAX_PATH];
_stprintf(strLog,_T("Leaving Func:- <%s>, Time inside the func <%d> ms"),m_strFuncName, GetTickCount()-m_dwEnterTime);
LOG(strLog)
}
private:
TCHAR m_strFuncName[MAX_PATH];
DWORD m_dwEnterTime;
};
void TestClass::TestFunction()
{
// I want to avoid writing the function name maually..
// Is there any macro (__LINE__)or some other way to
// get the function name inside a function ??
FuncTracer(_T("TestClass::TestFunction"));
/*
* Rest of the function code.
*/
}
I want to know if there is any way to get the name of the function from inside of a function? Basically I want the users of my class to simply create an object the same. They may not pass the function name.

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.
MSVC: __FUNCTION__, __FUNCDNAME__, __FUNCSIG__
GCC: __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)".

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

C++20 std::source_location::function_name
main.cpp
#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 f(int i) {
log("Hello world!"); // Line 16
return i + 1;
}
int f(double i) {
log("Hello world!"); // Line 21
return i + 1.0;
}
int main() {
f(1);
f(1.0);
}
Compile and run:
g++ -ggdb3 -O0 -std=c++20 -Wall -Wextra -pedantic -o source_location.out source_location.cpp
./source_location.out
Output:
info:source_location.cpp:16:int f(int) Hello world!
info:source_location.cpp:21:int f(double) Hello world!
so note how the call preserves caller information, so we see the desired main call location instead of log.
I have covered the relevant standards in a bit more detail at: What's the difference between __PRETTY_FUNCTION__, __FUNCTION__, __func__?
Tested on Ubuntu 22.04, GCC 11.3.

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.

Related

Create a flag for a Qt project or use QLoggingCategory

This is my first question on this website, I hope I'll do it just fine.
I'm doing a Qt Project at work using a lot of signals and slots and I would like to create a flag/macro/variable to activate/deactivate the use of std::cout to trace which signal is emitted and which slot is activated.
This is for debugging purpose, to know how the different components of the application exchange and avoid loops in signals/slots.
More specifically, I would have a flag/variable in my .pro :
QT_SIGNALS_SLOTS_LOG = true
and in my source code :
if(QT_SIGNALS_SLOTS_LOG)
std::cout << "MyClass::slotMySlot activated" << std::endl;
Questions :
1. Can I do something like that (using a variable of the .pro in the
code) ?
2. Is there a better way of doing that ?
UPDATE 1
Burich, this works just fine, thanks
Now I will try to code a Qt macro which I put in my slots and wich does all the work
Example :
Q_SIGNALS_SLOTS_LOG();
which gets the names of the Class and the Slot and do the
ifdef QT_SIGNALS_SLOTS_LOG
std::cout << "MyClass::slotMySlot activated" << std::endl;
endif
Is there a way of doing that ?
UPDATE 2
I used QLoggingCategory Class with this tutorial
I have a Class in my Utils folder with this code
#ifndef SIGNALSLOTDEBUG_H
#define SIGNALSLOTDEBUG_H
#include<QLoggingCategory>
Q_DECLARE_LOGGING_CATEGORY(logSignal)
Q_DECLARE_LOGGING_CATEGORY(logSlot)
inline static void debugSlotF( char const * caller_name )
{
qCDebug(logSlot) << __TIME__ << caller_name << "activated";
}
inline static void debugSlot(){
}
#define debugSlot() debugSlotF(__PRETTY_FUNCTION__)
#endif // SIGNALSLOTDEBUG_H
In my code I just call
void HorizontalPatternListScene::slotSelectionChanged(int i)
{
debugSlot();
....
I get this output :
log.slot: 12:06:54 void HorizontalPatternListScene::slotSelectionChanged(int) activated
And I can disable the stream by doing
QLoggingCategory::setFilterRules(
"log.slot=true\n"
"log.signal=false");
in my main.cpp
Set variable in pro:
DEFINES += QT_SIGNALS_SLOTS_LOG
Test it in code:
#ifdef QT_SIGNALS_SLOTS_LOG
std::cout << "MyClass::slotMySlot activated" << std::endl;
#endif
If you're willing to use C++11 features for this, you can so the following:
#ifdef DEBUGMYCODE
template<typename... ArgTypes>
inline void print(ArgTypes... args)
{
// trick to expand variadic argument pack without recursion
using expand_variadic_pack = int[];
// first zero is to prevent empty braced-init-list
// void() is to prevent overloaded operator, messing things up
// trick is to use the side effect of list-initializer to call a function on every argument, in order.
// (void) is to suppress "statement has no effect" warnings
#ifdef _WIN32
std::stringstream stream;
(void)expand_variadic_pack{0, ((stream << args), void(), 0)... };
std::wstring stuff = convert_to_utf16(stream.str());
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), stuff.c_str(), stuff.size(), nullptr, nullptr);
#else
(void)expand_variadic_pack{0, ((std::cout << args), void(), 0)... };
#endif
}
#else
#define debug_print(...)
#endif
I use this in my code as a general "print" function and add a debug enum on top to handle debug types being output at runtime.
It handles UTF-8 strings on Windows as a bonus, and handles anything that can be dumped to std::cout. You can also change what stream it outputs to, or really whatever the body of the function does.
If the macro DEBUGMYCODE is not defined, all calls to debug_print are fully removed by the preprocessor.
PS: if it's Qt you're coding, you should really use qDebug() which handles this for you in an entirely different manner.

Is it possible to create a function dynamically, during runtime in C++?

C++ is a static, compiled language, templates are resolved during compile time and so on...
But is it possible to create a function during runtime, that is not described in the source code and has not been converted to machine language during compilation, so that a user can throw at it data that has not been anticipated in the source?
I am aware this cannot happen in a straightforward way, but surely it must be possible, there are plenty of programing languages that are not compiled and create that sort of stuff dynamically that are implemented in either C or C++.
Maybe if factories for all primitive types are created, along with suitable data structures to organize them into more complex objects such as user types and functions, this is achievable?
Any info on the subject as well as pointers to online materials are welcome. Thanks!
EDIT: I am aware it is possible, it is more like I am interested in implementation details :)
Yes, of course, without any tools mentioned in the other answers, but simply using the C++ compiler.
just follow these steps from within your C++ program (on linux, but must be similar on other OS)
write a C++ program into a file (e.g. in /tmp/prog.cc), using an ofstream
compile the program via system("c++ /tmp/prog.cc -o /tmp/prog.so -shared -fPIC");
load the program dynamically, e.g. using dlopen()
You can also just give the bytecode directly to a function and just pass it casted as the function type as demonstrated below.
e.g.
byte[3] func = { 0x90, 0x0f, 0x1 }
*reinterpret_cast<void**>(&func)()
Yes, JIT compilers do it all the time. They allocate a piece of memory that has been given special execution rights by the OS, then fill it with code and cast the pointer to a function pointer and execute it. Pretty simple.
EDIT: Here's an example on how to do it in Linux: http://burnttoys.blogspot.de/2011/04/how-to-allocate-executable-memory-on.html
Below an example for C++ runtime compilation based on the method mentioned before (write code to output file, compile via system(), load via dlopen() and dlsym()). See also the example in a related question. The difference here is that it dynamically compiles a class rather than a function. This is achieved by adding a C-style maker() function to the code to be compiled dynamically. References:
https://www.linuxjournal.com/article/3687
http://www.tldp.org/HOWTO/C++-dlopen/thesolution.html
The example only works under Linux (Windows has LoadLibrary and GetProcAddress functions instead), and requires the identical compiler to be available on the target machine.
baseclass.h
#ifndef BASECLASS_H
#define BASECLASS_H
class A
{
protected:
double m_input; // or use a pointer to a larger input object
public:
virtual double f(double x) const = 0;
void init(double input) { m_input=input; }
virtual ~A() {};
};
#endif /* BASECLASS_H */
main.cpp
#include "baseclass.h"
#include <cstdlib> // EXIT_FAILURE, etc
#include <string>
#include <iostream>
#include <fstream>
#include <dlfcn.h> // dynamic library loading, dlopen() etc
#include <memory> // std::shared_ptr
// compile code, instantiate class and return pointer to base class
// https://www.linuxjournal.com/article/3687
// http://www.tldp.org/HOWTO/C++-dlopen/thesolution.html
// https://stackoverflow.com/questions/11016078/
// https://stackoverflow.com/questions/10564670/
std::shared_ptr<A> compile(const std::string& code)
{
// temporary cpp/library output files
std::string outpath="/tmp";
std::string headerfile="baseclass.h";
std::string cppfile=outpath+"/runtimecode.cpp";
std::string libfile=outpath+"/runtimecode.so";
std::string logfile=outpath+"/runtimecode.log";
std::ofstream out(cppfile.c_str(), std::ofstream::out);
// copy required header file to outpath
std::string cp_cmd="cp " + headerfile + " " + outpath;
system(cp_cmd.c_str());
// add necessary header to the code
std::string newcode = "#include \"" + headerfile + "\"\n\n"
+ code + "\n\n"
"extern \"C\" {\n"
"A* maker()\n"
"{\n"
" return (A*) new B(); \n"
"}\n"
"} // extern C\n";
// output code to file
if(out.bad()) {
std::cout << "cannot open " << cppfile << std::endl;
exit(EXIT_FAILURE);
}
out << newcode;
out.flush();
out.close();
// compile the code
std::string cmd = "g++ -Wall -Wextra " + cppfile + " -o " + libfile
+ " -O2 -shared -fPIC &> " + logfile;
int ret = system(cmd.c_str());
if(WEXITSTATUS(ret) != EXIT_SUCCESS) {
std::cout << "compilation failed, see " << logfile << std::endl;
exit(EXIT_FAILURE);
}
// load dynamic library
void* dynlib = dlopen (libfile.c_str(), RTLD_LAZY);
if(!dynlib) {
std::cerr << "error loading library:\n" << dlerror() << std::endl;
exit(EXIT_FAILURE);
}
// loading symbol from library and assign to pointer
// (to be cast to function pointer later)
void* create = dlsym(dynlib, "maker");
const char* dlsym_error=dlerror();
if(dlsym_error != NULL) {
std::cerr << "error loading symbol:\n" << dlsym_error << std::endl;
exit(EXIT_FAILURE);
}
// execute "create" function
// (casting to function pointer first)
// https://stackoverflow.com/questions/8245880/
A* a = reinterpret_cast<A*(*)()> (create)();
// cannot close dynamic lib here, because all functions of the class
// object will still refer to the library code
// dlclose(dynlib);
return std::shared_ptr<A>(a);
}
int main(int argc, char** argv)
{
double input=2.0;
double x=5.1;
// code to be compiled at run-time
// class needs to be called B and derived from A
std::string code = "class B : public A {\n"
" double f(double x) const \n"
" {\n"
" return m_input*x;\n"
" }\n"
"};";
std::cout << "compiling.." << std::endl;
std::shared_ptr<A> a = compile(code);
a->init(input);
std::cout << "f(" << x << ") = " << a->f(x) << std::endl;
return EXIT_SUCCESS;
}
output
$ g++ -Wall -std=c++11 -O2 -c main.cpp -o main.o # c++11 required for std::shared_ptr
$ g++ -ldl main.o -o main
$ ./main
compiling..
f(5.1) = 10.2
Have a look at libtcc; it is simple, fast, reliable and suits your need. I use it whenever I need to compile C functions "on the fly".
In the archive, you will find the file examples/libtcc_test.c, which can give you a good head start.
This little tutorial might also help you: http://blog.mister-muffin.de/2011/10/22/discovering-tcc/
#include <stdlib.h>
#include <stdio.h>
#include "libtcc.h"
int add(int a, int b) { return a + b; }
char my_program[] =
"int fib(int n) {\n"
" if (n <= 2) return 1;\n"
" else return fib(n-1) + fib(n-2);\n"
"}\n"
"int foobar(int n) {\n"
" printf(\"fib(%d) = %d\\n\", n, fib(n));\n"
" printf(\"add(%d, %d) = %d\\n\", n, 2 * n, add(n, 2 * n));\n"
" return 1337;\n"
"}\n";
int main(int argc, char **argv)
{
TCCState *s;
int (*foobar_func)(int);
void *mem;
s = tcc_new();
tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
tcc_compile_string(s, my_program);
tcc_add_symbol(s, "add", add);
mem = malloc(tcc_relocate(s, NULL));
tcc_relocate(s, mem);
foobar_func = tcc_get_symbol(s, "foobar");
tcc_delete(s);
printf("foobar returned: %d\n", foobar_func(32));
free(mem);
return 0;
}
Ask questions in the comments if you meet any problems using the library!
In addition to simply using an embedded scripting language (Lua is great for embedding) or writing your own compiler for C++ to use at runtime, if you really want to use C++ you can just use an existing compiler.
For example Clang is a C++ compiler built as libraries that could be easily embedded in another program. It was designed to be used from programs like IDEs that need to analyze and manipulate C++ source in various ways, but using the LLVM compiler infrasructure as a backend it also has the ability to generate code at runtime and hand you a function pointer that you can call to run the generated code.
Clang
LLVM
Essentially you will need to write a C++ compiler within your program (not a trivial task), and do the same thing JIT compilers do to run the code. You were actually 90% of the way there with this paragraph:
I am aware this cannot happen in a straightforward way, but surely it
must be possible, there are plenty of programing languages that are
not compiled and create that sort of stuff dynamically that are
implemented in either C or C++.
Exactly--those programs carry the interpreter with them. You run a python program by saying python MyProgram.py--python is the compiled C code that has the ability to interpret and run your program on the fly. You would need do something along those lines, but by using a C++ compiler.
If you need dynamic functions that badly, use a different language :)
A typical approach for this is to combine a C++ (or whatever it's written on) project with scripting language.
Lua is one of the top favorites, since it's well documented, small, and has bindings for a lot of languages.
But if you are not looking into that direction, perhaps you could think of making a use of dynamic libraries?
Yes - you can write a compiler for C++, in C++, with some extra features - write your own functions, compile and run automatically (or not)...
Have a look into ExpressionTrees in .NET - I think this is basically what you want to achieve. Create a tree of subexpressions and then evaluate them. In an object-oriented fashion, each node in the might know how to evaluate itself, by recursion into its subnodes. Your visual language would then create this tree and you can write a simple interpreter to execute it.
Also, check out Ptolemy II, as an example in Java on how such a visual programming language can be written.
You could take a look at Runtime Compiled C++ (or see RCC++ blog and videos), or perhaps try one of its alternatives.
Expanding on Jay's answer using opcodes, the below works on Linux.
Learn opcodes from your compiler:
write own myfunc.cpp, e.g.
double f(double x) { return x*x; }
compile with
$ g++ -O2 -c myfunc.cpp
disassemble function f
$ gdb -batch -ex "file ./myfunc.o" -ex "set disassembly-flavor intel" -ex "disassemble/rs f"
Dump of assembler code for function _Z1fd:
0x0000000000000000 <+0>: f2 0f 59 c0 mulsd xmm0,xmm0
0x0000000000000004 <+4>: c3 ret
End of assembler dump.
This means the function x*x in assembly is mulsd xmm0,xmm0, ret and in machine code f2 0f 59 c0 c3.
Write your own function in machine code:
opcode.cpp
#include <cstdlib> // EXIT_FAILURE etc
#include <cstdio> // printf(), fopen() etc
#include <cstring> // memcpy()
#include <sys/mman.h> // mmap()
// allocate memory and fill it with machine code instructions
// returns pointer to memory location and length in bytes
void* gencode(size_t& length)
{
// machine code
unsigned char opcode[] = {
0xf2, 0x0f, 0x59, 0xc0, // mulsd xmm0,xmm0
0xc3 // ret
};
// allocate memory which allows code execution
// https://en.wikipedia.org/wiki/NX_bit
void* buf = mmap(NULL,sizeof(opcode),PROT_READ|PROT_WRITE|PROT_EXEC,
MAP_PRIVATE|MAP_ANON,-1,0);
// copy machine code to executable memory location
memcpy(buf, opcode, sizeof(opcode));
// return: pointer to memory location with executable code
length = sizeof(opcode);
return buf;
}
// print the disassemby of buf
void print_asm(const void* buf, size_t length)
{
FILE* fp = fopen("/tmp/opcode.bin", "w");
if(fp!=NULL) {
fwrite(buf, length, 1, fp);
fclose(fp);
}
system("objdump -D -M intel -b binary -mi386 /tmp/opcode.bin");
}
int main(int, char**)
{
// generate machine code and point myfunc() to it
size_t length;
void* code=gencode(length);
double (*myfunc)(double); // function pointer
myfunc = reinterpret_cast<double(*)(double)>(code);
double x=1.5;
printf("f(%f)=%f\n", x,myfunc(x));
print_asm(code,length); // for debugging
return EXIT_SUCCESS;
}
compile and run
$ g++ -O2 opcode.cpp -o opcode
$ ./opcode
f(1.500000)=2.250000
/tmp/opcode.bin: file format binary
Disassembly of section .data:
00000000 <.data>:
0: f2 0f 59 c0 mulsd xmm0,xmm0
4: c3 ret
The simplest solution available, if you're not looking for performance is to embed a scripting language interpreter, e.g. for Lua or Python.
It worked for me like this. You have to use the -fpermissive flag.
I am using CodeBlocks 17.12.
#include <cstddef>
using namespace std;
int main()
{
char func[] = {'\x90', '\x0f', '\x1'};
void (*func2)() = reinterpret_cast<void*>(&func);
func2();
return 0;
}

How do I imitate the Microsoft version of __FUNCTION__ using gcc?

When I use the __FUNCTION__ macro/variable to print out debugging information, there seems to be a difference in what it outputs when using the Microsoft C++ compiler and gcc. For example, using the following trivial code:
class Foo
{
public:
void Bar(int a, int b, int c)
{
printf ("__FUNCTION__ = %s\n", __FUNCTION__);
}
};
int main (void)
{
Foo MyFoo;
MyFoo.Bar();
return 0;
}
Using the Microsoft Visual C++ compiler, I get
__FUNCTION__ = Foo::Bar
whereas when compiling using gcc (in this case on the Mac), I get
__FUNCTION__ = Bar
The second example is not ideal because I quite often have several classes with, say, Init() and Uninit() methods and in a debug output trace its virtually impossible to tell which one of these has been called as the class name will be missing. Now, I know you can use the __PRETTY_FUNCTION__ in place of __FUNCTION__ to get something like
__PRETTY_FUNCTION__ = void Foo::Bar(int, int, int)
Which is fine, but its a bit too verbose for what I need and gets a bit long for functions with a lot of parameters.
So my question is (at last), is there any way to get the output to look like simply Foo::Bar using gcc, as in the example above?
If you are using it for tracing, you can always use typeid(T).name() and just conditionally compile per platform. Certainly not as convenient as the macro, but it could work.
Vaguely similar to __CLASS__ macro in C++
The function-name sanctioned by the standard is defined as follows:
static const char __func__[] = "function-name ";
Example:
#include <iostream>
namespace meh {
void foobar() { std::cout << __func__ << std::endl; }
};
struct Frob {
void foobar() { std::cout << __func__ << std::endl; }
static void barfoo() { std::cout << __func__ << std::endl; }
};
int main () {
std::cout << __func__ << std::endl;
meh::foobar();
Frob().foobar();
Frob::barfoo();
}
However, output with g++:
main
foobar
foobar
barfoo
However, that is valid C++ behaviour:
ยง 8.4.1, 8: The function-local predefined variable __func__ is defined as if a definition of the form static const char __func__[] = "function-name ";
had been provided, where function-name is an implementation-defined string. It is unspecified whether such a variable has an address distinct from that of any other object in the program
I.e., you may not trust in its value. If you want to use non-portable extensions, have a look at a similar question: What's the difference between __PRETTY_FUNCTION__, __FUNCTION__, __func__? .

Call main() itself in c++?

#include <iostream>
#include <cstdlib>
int main() {
cout << "!!!Hello World!!!" << endl;
system("pause");
return main();
}
The above works, but it hardcoded the main() function. Is there a magic variable or macro to get the current running function?
Is it allowed in "C++"? No.
In practice, can you call main()? Yes.
Whatever the C++ Standard says, that doesn't stop the Linux g++ compiler from compiling code with main() in main().
#include <cstdlib>
#include <iostream>
using namespace std;
int main()
{
int y = rand() % 10; // returns 3, then 6, then 7
cout << "y = " << y << endl;
return (y == 7) ? 0 : main();
}
Which lets us do:
> g++ g.cpp; ./a.out
y = 3
y = 6
y = 7
Looking in to the assembly, we see that main is called just like any other function would be:
main:
...
cmpl $7, -12(%rbp)
je .L7
call main
...
.L7:
...
leave
ret
Not that this behavior is guaranteed, but it looks like g++ doesn't seem to really care about the standard, apart from this sarcastic warning with -pedantic
g.cpp:8: error: ISO C++ forbids taking address of function '::main'
The C++ Standard says that you may not call main() from your own code. As for getting the name of the current function, you could use the __FUNCTION__ macro, but once again this is not standard:
#include <iostream>
using namespace std;
void foo() {
cout << __FUNCTION__ << endl;
}
int main() {
foo();
}
should print "foo" or something similar if __FUNCTION__ is supported.
If a specific implementation allows this, it is not behaving correctly(a). The standard state quite explicitly in C++14, 3.6.1 Main function /3:
The function main shall not be used within a program.
(a) Keep in mind that many implementations follow some parts of the standard loosely, preferring power over strictness. That can have the unfortunate side effect that your code may not be portable to other compilers or even other versions of the same compiler.
Many implementations will also allow you to take the stricter view, such as using g++ -std=c++11 -Werror=pedantic which catches the particular issue bought up in this question, as well as quite a few others. It is that "mode" of translation that allows implementations to claim to be compliant with the standard, as per 1.4 Implementation compliance:
If a program contains a violation of any diagnosable rule ..., a conforming implementation shall issue at least one diagnostic message.
You'll see it's still quite possible to allow the code to compile and run in that case, since "diagnostic message" can mean a warning rather than an error.
Generally, no. For now it will be enough for you to know that the compiler needs to know the exact function you're calling at the compile time. You cannot do magic like, let's say
func = "my_function";
func();
if the called function name will change during runtime. (There are exceptions and ways around that, but you don't need that).
Don't think about that as a case of hard-coding: it is not. If you need to call the function, then you just write its name, and don't try to abstract it, or something.
Also, now would be a nice way to learn about the while loop, infinite loops and write without the function calls at all, e.g
int main()
{
while (1) {
cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
system("pause");
}
}

How to find the name of the current function at runtime?

After years of using the big ugly MFC ASSERT macro, I have finally decided to ditch it and create the ultimate ASSERT macro.
I am fine with getting the file and line number, and even the expression that failed. I can display a messagebox with these in, and Abort/Retry/Cancel buttons.
And when I press Retry the VS debugger jumps to the line containing the ASSERT call (as opposed to the disassembly somewhere like some other ASSERT functions). So it's all pretty much working.
But what would be really cool would be to display the name of the function that failed.
Then I can decide whether to debug it without trying to guess what function it's in from the filename.
e.g. if I have the following function:
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
ASSERT(lpCreateStruct->cx > 0);
...
}
Then when the ASSERT fires, the messagebox would show something like:
Function = CMainFrame::OnCreate
So, what's the simplest way of finding out the current function name, at runtime?
It should not use MFC or the .NET framework, even though I do use both of these.
It should be as portable as possible.
Your macro can contain the __FUNCTION__ macro.
Make no mistake, the function name will be inserted into the expanded code at compile time, but it will be the correct function name for each call to your macro. So it "seems like" it happens in run-time ;)
e.g.
#define THROW_IF(val) if (val) throw "error in " __FUNCTION__
int foo()
{
int a = 0;
THROW_IF(a > 0); // will throw "error in foo()"
}
The C++ preprocessor macro __FUNCTION__ gives the name of the function.
Note that if you use this, it's not really getting the filename, line number, or function name at runtime. Macros are expanded by the preprocessor, and compiled in.
Example program:
#include <iostream>
void function1()
{
std::cout << "my function name is: " << __FUNCTION__ << "\n";
}
int main()
{
std::cout << "my function name is: " << __FUNCTION__ << "\n";
function1();
return 0;
}
output:
my function name is: main
my function name is: function1
There's no standard solution. However, BOOST_CURRENT_FUNCTION is portable for all practical purposes. The header does not not depend on any of the other Boost headers, so can be used standalone if the overhead of the whole library is unacceptable.
__FUNCTION__ or __FUNC__ or __PRETTY_FUNCTION__
http://msdn.microsoft.com/en-us/library/b0084kay(VS.80).aspx
http://gcc.gnu.org/onlinedocs/gcc/Function-Names.html
In GCC you can use the __PRETTY_FUNCTION__ macro.
Microsoft also have an equivalent __func__ macro although I don't have that available to try.
e.g. to use __PRETTY_FUNCTION__ putting something like this at the beginning of your functions and you'll get a complete trace
void foo(char* bar){
cout << __PRETTY_FUNCTION__ << std::endl
}
which will output
void foo(char* bar)
You also have the __FILE__ and __LINE__ macros available under all standard c/c++ compilers if you want to output even more information.
In practice I have a special debugging class which I use instead of cout. By defining appropriate environment variables I can get a full program trace. You could do something similar. These macros are incredibly handy and it's really great to be able to turn on selective debugging like this in the field.
EDIT: apparently __func__ is part of the standard? didn't know that. Unfortunately, it only gives the function name and not the parameters as well. I do like gcc's __PRETTY_FUNC__ but it's not portable to other compilers.
GCC also supports __FUNCTION__.
You can use the __FUNCTION__ macro which at compile time will be expanded to the name of the function.
Here's an example of how to use it in an assert macro.
#define ASSERT(cond) \
do { if (!(cond)) \
MessageBoxFunction("Failed: %s in Function %s", #cond, __FUNCTION__);\
} while(0)
void MessageBoxFunction(const char* const msg, ...)
{
char szAssertMsg[2048];
// format args
va_list vargs;
va_start(vargs, msg);
vsprintf(szAssertMsg, msg, vargs);
va_end(vargs);
::MessageBoxA(NULL, szAssertMsg, "Failed Assertion", MB_ICONERROR | MB_OK);
}
C++20 std::source_location::function_name
No macros are needed now that we have proper standardization:
main.cpp
#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 f(int i) {
log("Hello world!"); // Line 16
return i + 1;
}
int f(double i) {
log("Hello world!"); // Line 21
return i + 1.0;
}
int main() {
f(1);
f(1.0);
}
Compile and run:
g++ -ggdb3 -O0 -std=c++20 -Wall -Wextra -pedantic -o source_location.out source_location.cpp
./source_location.out
Output:
info:source_location.cpp:16:int f(int) Hello world!
info:source_location.cpp:21:int f(double) Hello world!
so note how the call preserves caller information, so we see the desired main call location instead of log.
I have covered the relevant standards in a bit more detail at: What's the difference between __PRETTY_FUNCTION__, __FUNCTION__, __func__?
Tested on Ubuntu 22.04, GCC 11.3.
you can easily use func.
it will take back you current function name at runtime which raised the exception.
usage:
cout << __func__ << ": " << e.what();