Handmade Hero»Forums»Code
7 posts
Engine architecture hobbyist born on the wrong side of the country from where game-dev hubs reside. Gotta love that irony.
Compiler Issue: delete operator replacement 'has a different exception specifier' error.
Edited by Feed on
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.
Mārtiņš Možeiko
2568 posts / 2 projects
Compiler Issue: delete operator replacement 'has a different exception specifier' error.
Edited by Mārtiņš Možeiko 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.
7 posts
Engine architecture hobbyist born on the wrong side of the country from where game-dev hubs reside. Gotta love that irony.
Compiler Issue: delete operator replacement 'has a different exception specifier' error.
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.
Mārtiņš Možeiko
2568 posts / 2 projects
Compiler Issue: delete operator replacement 'has a different exception specifier' error.
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.
7 posts
Engine architecture hobbyist born on the wrong side of the country from where game-dev hubs reside. Gotta love that irony.
Compiler Issue: delete operator replacement 'has a different exception specifier' error.
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).
Mārtiņš Možeiko
2568 posts / 2 projects
Compiler Issue: delete operator replacement 'has a different exception specifier' error.
No problem. That's why there is forum here. To ask questions and get answers.