https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77726

--- Comment #2 from Liu Hao <lh_mouse at 126 dot com> ---
It isn't weired if you know how a Dynamic-Link Library (DLL) on Windows works
different than a Shared Object (SO) on Linux.

Windows does not have a dynamic linker such as `ld.so` on Linux. Symbols in a
DLL are resolved at build-time, in contrary to Linux, where symbols in a SO are
resolved at load-time. The DLL loader can resolve symbols to addresses, but it
isn't as powerful as linkers after all. Consequently, an executable cannot use
its strong symbols to override already-resolved weak ones in a DLL.

If the user does not define a sized deallocation function, the default one in
libstdc++*.dll is used, which calls the weak, default, non-sized deallocation
function in the same DLL, which is the only candidate when the DLL is built and
can't be overridden.

Possible solution:
The default sized deallocation function should not call the non-sized one
directly. We may introduce a static pointer-to-function which points to the
non-sized one initially. The default sized deallocation function should read
that pointer then call the function it points to. An executable that defines a
non-sized deallocation function should modify that pointer to point to the
user-provided non-sized deallocation function before any other code that may
allocate dynamic memory, possibly via an implicitly generated __constructor__
with high priority.

Question:
What will happen if both the executable and another DLL try to replace the
non-sized deallocation function?
It looks to me that on Linux such scenario will end up in multiple definitions.
In this case abort() or std::terminate() is possibly solution.

Reply via email to