Search code examples
c++linker-errorsrapidjson

Why linker error but not compile error when copying rapidjson::Document?


rapidjson::Document copy results to link error:

Error 5 error LNK2019: unresolved external symbol "private: __thiscall rapidjson::GenericValue,class rapidjson::MemoryPoolAllocator >::GenericValue,class rapidjson::MemoryPoolAllocator >(class rapidjson::GenericValue,class rapidjson::MemoryPoolAllocator > const &)" (??0?$GenericValue@U?$UTF8@D@rapidjson@@V?$MemoryPoolAllocator@VCrtAllocator@rapidjson@@@2@@rapidjson@@AAE@ABV01@@Z) referenced in function "public: __thiscall rapidjson::GenericDocument,class rapidjson::MemoryPoolAllocator >::GenericDocument,class rapidjson::MemoryPoolAllocator >(class rapidjson::GenericDocument,class rapidjson::MemoryPoolAllocator > const &)" (??0?$GenericDocument@U?$UTF8@D@rapidjson@@V?$MemoryPoolAllocator@VCrtAllocator@rapidjson@@@2@@rapidjson@@QAE@ABV01@@Z) C:\Layer.obj

I see that rapidjson::Document is a child of rapidjson::GenericValue which does not have a copy constructor:

    //! Copy constructor is not permitted.
private:
    GenericValue(const GenericValue& rhs);

I wonder why there is no compiler error but a linker error? What C++ tries to do?

I use MVC 2013, and rapidjson 0.11. Also here are similar threads:

  1. LNK2019: "Unresolved external symbol" with rapidjson
  2. Rapidjson cannot copy `rapidjson::Document`

Solution

  • You've partially answered your own question:

        //! Copy constructor is not permitted.
    private:
        GenericValue(const GenericValue& rhs);
    

    All classes have an implicit copy constructor: http://en.cppreference.com/w/cpp/language/copy_constructor#Implicitly-declared_copy_constructor

    The author of this code is trying to disable the implicit copy constructor by declaring it without a definition. With a declaration, this code can compile. Without a definition, it can't link, and thus you see your error.

    More specifically, that error message you see translates as follows: "The implicit copy-constructor of the GenericDocument class is calling the implicit copy-constructor of the GenericValue class. The copy-constructor in the GenericValue class is declared but not defined." The text that you see is in its own way much more specific, but obviously harder to read.

    In your code (likely something using rapidjson), there exists an accidental or deliberate call to a copy constructor for GenericDocument, which is causing this whole problem for you. In my case, I was passing a GenericDocument into a function as a parameter. If you're doing the same thing, you should pass the document by reference, so it's not copied.