0

When working with an existing project, having made some modifications to some external libraries, I am encountering issues of the following kind when building a library dependent upon another dynamically-linked library:

error LNK2001: unresolved external symbol "public: virtual void * __cdecl Foo::`scalar deleting destructor'(unsigned int)

error LNK2001: unresolved external symbol "public: virtual void * __cdecl Foo::`vector deleting destructor'(unsigned int)

If I run dumpbin /symbols on the offending .obj file I can clearly see these symbols as UNDEF.

What is interesting to me is that there are no complaints of other undefined symbols, and the destructor for Foo is not referenced at all in the object file symbol dump. The main references to these synthesized functions that I can find on StackOverflow are from people who have not defined their destructor, however I can clearly see Foo::Foo being exported from the library where Foo is defined (by running dumpbin /exports on the .lib).

This brings me to the core of my question: When does Visual Studio (2015) choose to synthesize these functions, and when does it decide that they should be linked from another translation unit?

Community
  • 1
  • 1
Thomas Russell
  • 5,870
  • 4
  • 33
  • 68
  • Have you checked the [canonical answer](https://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix)? No guarantee that it helps but it exists for a reason... – Max Langhof Oct 11 '19 at 15:14
  • I trust VS synthesizes those always when new Foo and/or new Foo[x] is somewhere in code. – Öö Tiib Oct 11 '19 at 15:32
  • @HansPassant `Foo` does not declare any user-defined `operator delete` or `operator delete[]`. Moreover, other libraries which use `Foo` (and indeed call `new Foo`/`delete Foo`) do not have any problem linking against the library containing Foo. – Thomas Russell Oct 11 '19 at 15:34
  • To the person who voted to close - I described my problem for background information. My question is not asking for "debugging help", I am simply asking when MSVC synthesizes these functions. :) – Thomas Russell Oct 11 '19 at 15:35

1 Answers1

0

I encounter the same behavior in VS2019 in our project. However in VS2022 (as well as GCC and Clang) the same code compiles/links just fine.

To me (and to answer the question), this is a compiler bug in VS2019 (and below?) and in our scenario (where Foo has a few base classes with lots of 'virtualness' involved) it was caused by

// Foo.h
~Foo() = default;   //< the culprit

However, any of these two workarounds fixed it:

  • Explicitly declaring the DTor in the header (definition in foo.cpp did NOT help):

    // Foo.h
    ~Foo() {};
    
  • Using (at least one) of the missing operators in the CPP which refuses to link:

    // Foo.h
    ~Foo() = default;
    
    // Other.cpp
    void bar()
    {
      auto p = new Foo();
      delete p;
    }
    
cbielow
  • 416
  • 4
  • 3