Reputation: 1746
I just ran c++filt
to demangle when I had a duplicate symbol error:
$ c++filt __ZN4uiuclsERNSt3__113basic_ostreamIcNS0_11char_traitsIcEEEERKNS_5StackE
uiuc::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, uiuc::Stack const&)
but the actual function looks like this [within the uiuc
namespace]:
std::ostream & operator<<(std::ostream & os, const Stack & stack)
How can I get the demangled output to
std::ostream &
std::ostream
instead of
std::__1::basic_ostream<char, std::__1::char_traits<char> >&
. There is the __
right after std::
that I don't get and the template-like input. Is ostream implemented as a template?I ask because there are other return turn types that I won't be able to easily map. I am dealing with a small file for practice.
I am running on macOS
and tried the different c++filt
--format
options for the compiler but didn't see any that gave me a different output.
Upvotes: 1
Views: 168
Reputation: 22162
- show the return type:
std::ostream &
Return types of ordinary functions are not part of their signature or their mangled name. There is no way to obtain the return type from a mangled name. To do this you need to lookup the header file which declares the function.
This is different for function templates, though.
- show
std::ostream
instead ofstd::__1::basic_ostream<char, std::__1::char_traits<char> >&
. There is the__
right afterstd::
that I don't get and the template-like input. Isostream
implemented as a template?
The standard defines that std::ostream
is a type alias for std::basic_ostream<char, std::char_traits<char>>
, which is a template specialization of the class template std::basic_ostream
. There are specializations of this for every character type that the stream could use, e.g. std::basic_ostream<wchar_t, std::char_traits<wchar_t>>
(aliased as std::wostream
) for wide character streams.
Type aliases are resolved during compilation to the actual type name they refer to, so the mangled name does not contain any information about the alias that was used in the declaration. It would also make no sense to have a differentiation, because the function should be the same, no matter what alias was used, so the symbol name cannot differ on it.
You could in principle run a search-and-replace for the standard library's common aliases. I don't know any tool that does that at the top of my head. You get used to the non-alias names quickly anyway.
::__1
is an inline namespace used by the standard library to be able to define multiple versions of standard library symbols transparently. Names in the inline namespace can be looked up as if they were declared in the enclosing namespace, so when you use e.g. std::ostream
, the library may actually declare ostream
not in the std
namespace, but in std::__1
, which will still be found if __1
is an inline namespace.
This is an implementation detail that you should simply ignore. The double underscore in the name is a good indicator that it is an implementation detail that you don't need to care about, because identifiers with a double underscore are reserved for use by the language implementation.
Again, you could probably search-and-replace such inline namespaces from the standard library namespace, but I am not aware whether any tool does that and again, one gets used to it quickly.
Upvotes: 1