18

After compilation with g++-4.9.3 -std=c++11 the code

#include <iostream>
#include <typeinfo>
using namespace std;
int main() { cout << typeid([]{}).name() << endl; }

outputs Z4mainEUlvE_ as the mangled name of the given lambda on Linux x86_64. However, the c++filt tool is unable to unmangle it. It just outputs the input given to it, Z4mainEUlvE_.

How do I unmangle it?

jotik
  • 17,044
  • 13
  • 58
  • 123

4 Answers4

17

You can use GCC's special abi::__cxa_demangle function:

#include <memory>
#include <cstdlib>
#include <cxxabi.h>
#include <iostream>

// delete malloc'd memory
struct malloc_deleter
{
    void operator()(void* p) const { std::free(p); }
};

// custom smart pointer for c-style strings allocated with std::malloc
using cstring_uptr = std::unique_ptr<char, malloc_deleter>;

int main()
{
    // special function to de-mangle names
    int error;
    cstring_uptr name(abi::__cxa_demangle(typeid([]{}).name(), 0, 0, &error));

    if(!error)
        std::cout << name.get() << '\n';
    else if(error == -1)
        std::cerr << "memory allocation failed" << '\n';
    else if(error == -2)
        std::cerr << "not a valid mangled name" << '\n';
    else if(error == -3)
        std::cerr << "bad argument" << '\n';
}

Output:

main::{lambda()#1}

According to The Documentation this function returns a c-style zero-terminated string allocated using std::malloc which the caller needs to free using std::free. This example uses a smart pointer to free the returned string automatically at the end of the scope.

Galik
  • 47,303
  • 4
  • 80
  • 117
10

Using c++filt version 070207 20070207:

$ c++filt -n Z4mainEUlvE_
main::'lambda'()

Although as the commenters have suggested, these names aren't always entirely helpful.

davidb
  • 448
  • 3
  • 9
  • Alternatively you can just pipe the output of the program to `c++filt`, like `./a.out | c++filt` – vsoftco Apr 10 '16 at 21:32
2

If you don't need it inside your code, and its only for fun then use an online tool like http://d.fuqu.jp/c++filtjs/ which for Z4mainEUlvE_ it returns main::{lambda()#1}.

Other tools can be found under this Stack Overflow question.

Community
  • 1
  • 1
marcinj
  • 48,511
  • 9
  • 79
  • 100
1

You could try using boost::core::demangle but I don't know if your results will be any different.

For example

#include <boost/core/demangle.hpp>
#include <iostream>

int main () {
  std::cout  << boost::core::demangle (typeid ([](){}).name ()) << std::endl;
}
Zack
  • 306
  • 1
  • 4