More reasons i like C++


Error 1 error LNK2019: unresolved external symbol “public: void __thiscall

 CNamedItemTable::AddIfNotSet(class ATL::CStringT<unsigned short,class

 ATL::StrTraitATL<unsigned short,class ATL::ChTraitsCRT<unsigned short> > >

 const &,class CSmartPtr<class CGlyph,class CGlyph,class

 CDefaultSmartPointerTraits<class CGlyph> >)” (?AddIfNotSet@CNamedItemTable@@

QAEXABV?$CStringT@GV?$StrTraitATL@GV?$ChTraitsCRT@G@ATL@@@ATL@@@ATL@@V?$C

SmartPtr@VCGlyph@@V1@V?$CDefaultSmartPointerTraits@VCGlyph@@@@@@@Z) referenced

 in function “private: long __thiscall CTypeData::BindHelper_BaseNameToGeneric(

class CInheritance &,class CBindData const &,struct LocationContext &,enum

NamespaceInclusionFlags::_Enum,class CTypeRef *,struct INameProvider * *)”

(?BindHelper_BaseNameToGeneric@CTypeData@@AAEJAAVCInheritance@@ABVCBindData@

@AAULocationContext@@W4_Enum@NamespaceInclusionFlags@@PAVCTypeRef@@PAPAUINam

eProvider@@@Z) TypeData.obj

 

 

Ohhhhh, of course… how useful!!  Name mangling is awesome!

 

 

Edit: Adding picture for clarification

 

 


Comments (19)

  1. Uwe Keim says:

    I thought I read somewhere that the error message in the upcoming VC++ 2005 are improved for readability and understandability?!?

  2. DrPizza says:

    I think that’s pretty disingenuous, really, given that it does actually give you the unmangled name that it’s looking for.

    The more legitimate concern (as in, the issue that’s responsible for more confusion) is that it undoes typedefs. Though it’s obvious *why* it does this it would be nice if there were a way to reverse the substitution (akin to what stlfilt does). Of course, doing this in a general and useful way is left as an exercise for the reader….

  3. Hi Cyrus,

    Probably (well, certainly) not useful in your specific context here above but, anyway, that’s a perferct time for me to mention a tool that has been very useful when I was trying to decrypt error messages from the STL:

    http://www.bdsoft.com/tools/stlfilt.html

    Believe me, sometimes STL error messages are even more unreadable than the one you show.

  4. DrPizza: Disingenuous how? That’s *exactly* the error message i got in my task list from the linker. I wouldn’t mind a "simple error" saying:

    Error 1 error LNK2019: unresolved external symbol "public: void CNamedItemTable::AddIfNotSet"

    and the more complicated one, but really, all i’m left with is having to decipher that message, which really isn’t that easy frankly.

  5. David: Very cool! Thanks for that tip!

  6. DrPizza says:

    "DrPizza: Disingenuous how? That’s *exactly* the error message i got in my task list from the linker. I wouldn’t mind a "simple error" saying: "

    Disingenuous because name mangling has nothing to do with anything, because it’s giving you the unmangled names.

    What makes those unmangled names hard to read isn’t name mangling; it’s the use of "real" types where before one had a typedef.

    "and the more complicated one, but really, all i’m left with is having to decipher that message, which really isn’t that easy frankly. "

    But you’re not left having to do anything with the mangled name. Using this error message as grounds for your sarcastic comment that "Name mangling is awesome" is disingenuous. The message would be no clearer if it were:

    Error 1 error LNK2019: unresolved external symbol "public: void __thiscall

    CNamedItemTable::AddIfNotSet(class ATL::CStringT<unsigned short,class

    ATL::StrTraitATL<unsigned short,class ATL::ChTraitsCRT<unsigned short> > >

    const &,class CSmartPtr<class CGlyph,class CGlyph,class

    CDefaultSmartPointerTraits<class CGlyph> >)" referenced in function "private:

    long __thiscall CTypeData::BindHelper_BaseNameToGeneric(class CInheritance &,

    class CBindData const &,struct LocationContext &,enum

    NamespaceInclusionFlags::_Enum,class CTypeRef *,struct INameProvider * *)"

    It’s the typedef substitution that’s killer, not name mangling. It’s the typdef substitution that leaves you scratching your head, because *you* certainly don’t have methods that take "ATL::CStringT<unsigned short, …>". They just take something like a CString. If the error were something like:

    Error 1 error LNK2019: unresolved external symbol

    public: void CNamedItemTable::AddIfNotSet(const CString&, CGlyphPtr)

    referenced in function

    private: long CTypeData::BindHelper_BaseNameToGeneric(CInheritance&, const CBindData&, LocationContext&, NamespaceInclusionFlags::_Enum, CTypeRef*, INameProvider**)

    (putting typedefs back in, getting rid of spurious struct/class keywords, getting rid of the defaulted in calling convention) then the problem would go away.

  7. DrPizza: Yes i am.

    The mangled names are included in that mess, so i’m forced to try and twease it apart when looking at it. It would still be difficult with typedef’s expanded, but a lot easier than when i’m trying to figure out what’s going on and i’m seeing thigns like (?

    AddIfNotSet@CNamedItemTable@@QAEXABV?$CStringT@GV?$StrTraitATL@GV?$ChTraitsCRT@G@ATL@@@ATL@@@ATL@@V?$CSmartPtr@VCGlyph@@V1@V?$CDefaultSmartPointerTraits@VCGlyph@@@@@@@Z) jammed into the middle of it.

    I mean !@#!$(*!#!()*@!# it @!#!(#*!)@(#*!)@(* isn’t @!*#!)_(#@*!@#)(*@ to (#*!_@#*!)@* read !)@#_!@#(!)@_ something @!#!(&@#!@) that @!#!@#! has #$(%*$#(@% stuff !@#_*!@#) like !@#*_!@)# this !@)#_*_(%^&*$# interspersed.

    Unless you like perl that is 🙂

    And, it wasn’t being disengenous. There are merely compounded factors here and i was pointing out the one i was having the most difficulty with.

    If you have no problem with the mangling but do with the typedefs, more power to you.

  8. ChrisR says:

    Actually, I think the name mangling is useful. You would never know the name the linker was *actually* looking for if you couldn’t see the mangled name.

    The real problem here is the presentation. Like DrPizza said, a way to "undo" all the typenames back to their typedefs would help, and so would a more functional output window.

    I think the error as formatted below would help:

    Error 1 error LNK2019:

    unresolved external symbol:

    public: void CNamedItemTable::AddIfNotSet([click to view parameter list])

    [click for mangled name]

    referenced in function:

    private: long CTypeData::BindHelper_BaseNameToGeneric([click to view parameter list])

    [click for definition]

    The problem with most error messages that come up in template based code is their length. It’s almost impossible to decipher the error messages that span 10 full length lines in the output window, no matter who you are. I think it would be helpful if there was a better method of getting to each individual piece of error message data.

  9. DrPizza: That string is verbatim how it is presented to me when i do a compile. Line breaks would do wonders, as would not showing me the fully qualified and expanded names. But *for me* it is the name mangling that makes it unintelligible.

    As i said before: "If you have no problem with the mangling but do with the typedefs, more power to you. "

    I, however, do have more of a problem with the mangling than the typedefs, which is why i was complaining about it.

    Is there a whole lot of stuff that could be done to improve this? Yes. Does mangling help anyone but someone who works on the linker? Probably not. Would it help to have a way to remove it? Yes.

    That’s all i’m saying.

  10. DrPizza says:

    "Yes i am. "

    No, you’re not.

    "The mangled names are included in that mess, so i’m forced to try and twease it apart when looking at it."

    Then there’s either something wrong with you, or I have some incredible power that you don’t. ‘cos when I get linker errors, I don’t bother looking at the mangled names. Why not? Because they’re 99.99% of the time meaningless gibberish. So why waste my time with looking at them? It doesn’t provide me with any extra insight into the problem, so I just ignore them. And as soon as I ignore them, any problems related to name mangling being confusing and messy and kludgy instantly vanish. It’s really rather clever.

    And since (surely?!) the linker inserts a linebreak between the referenced function and the referencing function, the mangled garbage isn’t really "jammed into the middle", but rather "dangling on the end". If it doesn’t put in a linebreak there, it ought to.

  11. DrPizza says:

    But I still don’t get *why* because what on *earth* is compelling you to read the mangled names? Just because they’re there?

  12. I’ve added a picture for clarification purposes.

    You say "But I still don’t get *why* because what on *earth* is compelling you to read the mangled names? Just because they’re there?"

    Because when i look at that on my screen my eyes are drawn toward th emangled portion. I do *not* know why that is, it’s simply the way my eyes and brain work. Maybe it’s all the

    @@@@@

    portions. It’s very heavyweight and it seems to drown out the rest of the text for me. Who knows.

    As someone mentioned, it would be quite nice if things were trimmed down into something simple and immediately grokkable with a way to get at the full info.

    The VS2005 debugger does that with + signs where they hide a lot of stuff that they figure woon’t be useful to you by default. If, for example, i just saw:

    Error LNK2019: unresolved external symbol

    "public: void __thiscall CNamedItemTable::AddIfNotSet

    + Expand for full Error

    then i’d have a much easier time with this. As it is, the presentation of the mangled names into the view is decidely inconvenient for *me*.

  13. zdeslav says:

    the title should really be "more reasons i like visual c++", since there is nothing in C++ standard that states the rules for name mangling or what compiler should output. so this is clearly having to do with the compiler/linker you are using, not C++ per se. of course, i’m aware that most compilers would produce similar message, but nothing stops the compiler team to add more helpful messages.

  14. ChrisR says:

    @Cyrus:

    Can I ask what IDE you are using? You say "The VS2005 debugger does that with + signs where they hide a lot of stuff that they figure woon’t be useful to you by default.", which makes it seem as if you are not using VS2005, but the picture you added definately does not look like VS2003.

  15. Chris: I’m using VS2005.

    I’m confused about your confusion. 🙂

  16. Timbo says:

    ChrisR: the VS2005 debugger uses + signs to hide detailed info; the VS2005 compile/link error list window does not.

  17. ChrisR says:

    @Cyrus: Sorry for the confusion. I missed the part where you said "debugger".

    @Timbo: Thanks for the clarification.

Skip to main content