Compiler Issue: delete operator replacement 'has a different exception specifier' error.

BEFORE YOU BEGIN READING

Please know that this is not a HH issue, but an overall compilation issue i am having, and with how speedy the responses from my last question where, i thought i would try it out here again. Thanks if you take your time to read/answer.

Ok so the actual issue.

I am attempting to overload my new/delete operators globally to utilize the winapi GlobalAlloc/GlobalFree calls (and move father away from c runtime). While the overloaded new appears to give no compilation issues, the delete appears to spark up a storm with multiple errors. Im going to post the full error log, but also give a bit of an insight into how i am doing everything if it is actually somthing i am doing wrong.

Error Log
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
"C:\Program Files (x86)\JetBrains\CLion 2016.1.1\bin\cmake\bin\cmake.exe" --build C:\Users\Orcu\.CLion2016.1\system\cmake\generated\Blockade-817364e6\817364e6\Debug --target Blockade -- -j 8
Scanning dependencies of target Blockade
[ 20%] Building CXX object CMakeFiles/Blockade.dir/blockMain.cpp.obj
[ 40%] Building CXX object CMakeFiles/Blockade.dir/blockPlatform_win32.cpp.obj
[ 60%] Building CXX object CMakeFiles/Blockade.dir/blockWindowManager.cpp.obj
[ 80%] Building CXX object CMakeFiles/Blockade.dir/blockMemory.cpp.obj
In file included from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/ext/new_allocator.h:33:0,
                 from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/x86_64-w64-mingw32/bits/c++allocator.h:33,
                 from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/bits/allocator.h:46,
                 from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/bits/stl_tree.h:62,
                 from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/map:60,
                 from C:\Users\Orcu\ClionProjects\Blockade\blockMemory.cpp:8:
C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/new:96:41: error: declaration of 'void operator delete(void*) noexcept (true)' has a different exception specifier
   __attribute__((__externally_visible__));
                                         ^
In file included from C:\Users\Orcu\ClionProjects\Blockade\blockMemory.cpp:5:0:
C:\Users\Orcu\ClionProjects\Blockade\blockMemory.h:20:13: error: from previous declaration 'void operator delete(void*)'
 inline void operator delete (void* ptr) { heapFree(ptr); }
             ^
In file included from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/ext/new_allocator.h:33:0,
                 from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/x86_64-w64-mingw32/bits/c++allocator.h:33,
                 from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/bits/allocator.h:46,
                 from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/bits/stl_tree.h:62,
                 from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/map:60,
                 from C:\Users\Orcu\ClionProjects\Blockade\blockMemory.cpp:8:
C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/new:98:41: error: declaration of 'void operator delete [](void*) noexcept (true)' has a different exception specifier
   __attribute__((__externally_visible__));
                                         ^
In file included from C:\Users\Orcu\ClionProjects\Blockade\blockMemory.cpp:5:0:
C:\Users\Orcu\ClionProjects\Blockade\blockMemory.h:21:13: error: from previous declaration 'void operator delete [](void*)'
 inline void operator delete[] (void* ptr) { heapFree(ptr); }
             ^
In file included from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/ext/new_allocator.h:33:0,
                 from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/x86_64-w64-mingw32/bits/c++allocator.h:33,
                 from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/bits/allocator.h:46,
                 from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/string:41,
                 from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/bits/locale_classes.h:40,
                 from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/bits/ios_base.h:41,
                 from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/ios:42,
                 from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/ostream:38,
                 from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/iostream:39,
                 from C:\Users\Orcu\ClionProjects\Blockade\blockMain.cpp:4:
C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/new:96:41: error: declaration of 'void operator delete(void*) noexcept (true)' has a different exception specifier
   __attribute__((__externally_visible__));
                                         ^
In file included from C:\Users\Orcu\ClionProjects\Blockade\blockMain.cpp:3:0:
C:\Users\Orcu\ClionProjects\Blockade\blockMemory.h:20:13: error: from previous declaration 'void operator delete(void*)'
 inline void operator delete (void* ptr) { heapFree(ptr); }
             ^
In file included from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/ext/new_allocator.h:33:0,
                 from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/x86_64-w64-mingw32/bits/c++allocator.h:33,
                 from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/bits/allocator.h:46,
                 from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/string:41,
                 from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/bits/locale_classes.h:40,
                 from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/bits/ios_base.h:41,
                 from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/ios:42,
                 from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/ostream:38,
                 from C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/iostream:39,
                 from C:\Users\Orcu\ClionProjects\Blockade\blockMain.cpp:4:
C:/mingw-w64/mingw64/x86_64-w64-mingw32/include/c++/new:98:41: error: declaration of 'void operator delete [](void*) noexcept (true)' has a different exception specifier
   __attribute__((__externally_visible__));
                                         ^
In file included from C:\Users\Orcu\ClionProjects\Blockade\blockMain.cpp:3:0:
C:\Users\Orcu\ClionProjects\Blockade\blockMemory.h:21:13: error: from previous declaration 'void operator delete [](void*)'
 inline void operator delete[] (void* ptr) { heapFree(ptr); }
             ^
mingw32-make.exe[3]: *** [CMakeFiles/Blockade.dir/blockMemory.cpp.obj] Error 1
mingw32-make.exe[3]: *** Waiting for unfinished jobs....
CMakeFiles\Blockade.dir\build.make:133: recipe for target 'CMakeFiles/Blockade.dir/blockMemory.cpp.obj' failed
C:\Users\Orcu\ClionProjects\Blockade\blockMain.cpp: In function 'int main(int, char**)':
C:\Users\Orcu\ClionProjects\Blockade\blockMain.cpp:12:69: warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
     windowManager->createWindow(testWindowHandle, "test", 0, 0, 0, 0);
                                                                     ^
CMakeFiles\Blockade.dir\build.make:61: recipe for target 'CMakeFiles/Blockade.dir/blockMain.cpp.obj' failed
mingw32-make.exe[3]: *** [CMakeFiles/Blockade.dir/blockMain.cpp.obj] Error 1
mingw32-make.exe[2]: *** [CMakeFiles/Blockade.dir/all] Error 2
CMakeFiles\Makefile2:66: recipe for target 'CMakeFiles/Blockade.dir/all' failed
mingw32-make.exe[1]: *** [CMakeFiles/Blockade.dir/rule] Error 2
CMakeFiles\Makefile2:78: recipe for target 'CMakeFiles/Blockade.dir/rule' failed
mingw32-make.exe: *** [Blockade] Error 2
makefile:117: recipe for target 'Blockade' failed


P.S: Yes those are Cmake related things, i am using Clion as my IDE.

Now for a bit of the code flow.

The overloads are defined as such in a memory header.

1
2
3
4
5
6
7
8
9
//Heap alloc/free function pointers.
extern void*(*heapAlloc)( size_t );
extern void(*heapFree)( void* );

//Global allocation overides
inline void* operator new (size_t size) { heapAlloc(size); }
inline void* operator new[] (size_t size) { heapAlloc(size); }
inline void operator delete (void* ptr) { heapFree(ptr); }
inline void operator delete[] (void* ptr) { heapFree(ptr); }


The function pointers are a way to abstract the winapi calls.

In the source, i have the function pointers assigned to the platform abstractions declarations.

1
2
void*(*heapAlloc)( size_t ) = platform::globalAlloc;
void (*heapFree)( void* ) = platform::globalFree;


The platform abstraction has nothing but the function declarations for platform opaque api calls, so i dont see a reason to show those.

In the win32 platform implementation, the platform functions are defined as such.

1
2
3
4
5
6
7
    void* globalAlloc(size_t size){
        return GlobalAlloc(0, size);
    }

    void globalFree(void* ptr){
        GlobalFree(ptr);
    }


Initially i was doing a new/delete method that use function pointers passed as operator arguments to decide what type of allocations too do, and it was working, but then i decided that it was more complex than i needed and limited the flexibility of the engine a bit so i scraped them in favor of just basic overloads with no additional arguments. However i cannot compile now for whatever reason because of the errors outputted into the log i posted.

If anyone could help, it would be greatly appreciated.

Edited by Feed on
Well the error is pretty obvious, no? Compiler is telling you exactly what is wrong:

1
error: declaration of 'void operator delete(void*) noexcept (true)' has a different exception specifier

In C++ operator delete must never throw. You indicate that with throw() after parameter list. Or noexcept if you are on C++11 or newer.

And I'm not sure operator overloads can be inline. I think they must have external visibility. So remove "inline" from definitions.

Edited by Mārtiņš Možeiko on
It was obvious and at the same time it wasn't, because i had never encountered that issue before. Thanks for the answer though, adding noexcept to the delete overloads fixed the issue.

As for the inline; not adding the inline resulted in multiple definition errors regardless of header guards, and the inline fixed that.
That's because you are supposed to put definitions of these operators in only one translation unit. There's no need to put them in header file.
I had actually attempted to do that a few times but kept getting compilation errors.

After you saying that's they way is should be done, then i attempted it again but this time it actually compiled, which is great because now the global function pointers can be removed since the definitions can call the platform alloc/free fucntions directly.

Thanks again! (sorry if this issue was super 101 for you).
No problem. That's why there is forum here. To ask questions and get answers.