Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to unmangle mangled names of C++ lambdas?

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?

like image 913
jotik Avatar asked Apr 10 '16 19:04

jotik


People also ask

Does C have name mangling?

Since C is a programming language that does not support name function overloading, it does no name mangling.

What is mangling and Demangling in C++?

When XL C/C++ compiles a C++ program, it encodes (mangles) all function names and certain other identifiers to include type and scoping information. The name mangling is necessary to accommodate overloading of C++ functions and operators.

How does name mangling work?

Name mangling is the encoding of function and variable names into unique names so that linkers can separate common names in the language. Type names may also be mangled. Name mangling is commonly used to facilitate the overloading feature and visibility within different scopes.


2 Answers

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.

like image 87
Galik Avatar answered Dec 23 '22 02:12

Galik


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.

like image 20
davidb Avatar answered Dec 23 '22 03:12

davidb