Tag: des symbol ext vector allows ice to call handle Lang recursively
Previously written in the Baidu space in this article:
[Baidu Space] [Original] Global operator delete overload to DLL
First, correct a word "overloaded", operator New/delete is replaced (replacement), not overloaded. As long as any one compilation unit defines a replacement function and does not need a global declaration, it replaces the global default operator New/delete, which behaves much like the GCC strong symbol/weak symbol.
Recently looked over the C++03 standard:
3. The program ' s de?nitions is used instead of the default versions supplied by the implementation (18.6). Such replacement occurs prior to program startup (3.2, 3.6). The program ' s de?nitions shall is not being speci?ed as inline. No Diagnostic is required.
This means that the standard is not allowed inline operator New/delete. The reason is also very simple, new/delete is replacement, is the link level symbol substitution. If it is inline, it is likely that there is no symbol generated, it is not possible to implement replacement, resulting in only the header file, the reference declaration of the compilation Unit will have replacement, which is inconsistent with the "global substitution."
However, the standard also said no diagnostic is required, it is estimated because of compatibility reasons, after all, this standard comes out, there are many compilers support this. So MSVC will give a warning at most, and clang back to a warning that can be turned off.
So the use of inline operator new/delete is not standard, may cause problems, of course, there is certainty (luck) words, and will not go wrong. For example, I've been using it before, and some famous open source projects are also in use.
But this way gives me a great convenience, is can fall back to default operator new:
By default, as long as any one of the files defined operator New/delete, it will replacment, so the default New/delete has been overwritten, there is no way to access.
After using the inline operator delete, the default operator delete can still be called in the custom operator delete.
//global.hextern void__declspec (dllexport) baldeglobaldelete (void*ptr); inlinevoid operator Delete(void*ptr) { returnbaldeglobaldelete (PTR);}//Mem.cxx#include <Global.h>extern voidDefaultdelete (void*ptr);voidBaldeglobaldelete (void*ptr) { //Note This was a demo code that isn't used in practice int* p = (int*) ptr-1; intMagic = *p; if(Magic = =blade_mem_magic) Bladeinternalfree (P); Elsedefaultdelete (PTR);}//Defaultdelete.cxx//This file doesn ' t include global.h//inline operator Delete is not visible and no replacement happens!
If define operator delete without inline (and in. cpp), replacement always happens, whether it decl is the visible or not (c ORRECT/STD conformed behavior)
voidDefaultdelete (void*ptr) { //Call the built in delete return::operator Delete(PTR);}
If there is no inline (and the definition is written in the CPP), replacement must occur, so defaultdelete will not invoke the default delete, but will recursively invoke the custom operator delete, Baldeglobaldelete, so the stack will overflow.
With inline (MSVC's debug build also needs to change the optimization option to enable inline), the weird thing happens, actually there is no real replacment, as long as the global.h header file is not included, you can fall back to the default delete.
This is a very tricky way, mainly to ensure the consistency of the New/delete, compatible with the three-party default new. In fact, portability and stability are not good, is a negative. Recently, in order to standards-conformation, this hack has been removed and a more standard approach has been taken, removing the substitution of the global operator delete.
Questions about DLL boundary.
There are many ways to solve this problem, such as com-like (virutal destroy), or Factory + deleter, or use a unified allocation routine (such as LocalAlloc).
Blade uses the following specifications to guarantee:
1. Cross-DLL classes must be pure virtual base classes, or, virtual Destructors + in-class custom operator New/delete, so the convenience is that you can directly cross DLL delete, the C + + standard guarantee.
Allocations and releases of the underlying type, such as new Int[count], do not allow cross-DLL management, and in practice, cross-function management is not allowed. Personally, the design that requires the user to call free strdup is not a good design.
Using shared_ptr + deleter is the best way, but is not currently considered, because it is still based on c++03.
2. The common header file is not allowed to include <vector> <string> and other containers to avoid the memory distribution of different versions of STL objects
In the case of cross-DLL, regardless of the above method, for the DLL can be unloaded, there will still be problems, such as dll/so Uninstall, whether it is virtual destory or deleter, because the binary executable code has unmap the process address space is not accessible, So the need for good
Life cycle management and cleanup routine. can also be lazy, prohibit unloading, such as the use of get_module_handle_ex_flag_pin/rtld_nodelete.
[Original] inline operator delete & DLL boundary