Может кто-нибудь объяснить природу этой ошибки компиляции С++? Я разбираюсь/узнаю о перегрузке глобальных операторов new, delete и их вариантах. Я прочитал пару статьи on , но я не мог " t найти тот, который, кажется, обращается именно к этому.
Код
foo.h
:
#ifndef foo_h
#define foo_h
void* operator new(size_t);
void* operator new[](size_t);
void operator delete(void*);
void operator delete[](void*);
#endif // foo_h
foo.cpp
:
#include <foo.h>
#include <iostream>
void* operator new(size_t size) { return NULL; }
void* operator new[](size_t size) { return NULL; }
void operator delete(void* p) { }
void operator delete[](void* p) { }
Ошибка компиляции
>g++ -g -std=c++14 -I./ -c foo.cpp -o foo.o
In file included from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/ext/new_allocator.h:33:0,
from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/x86_64-pc-cygwin/bits/c++allocator.h:33,
from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/allocator.h:46,
from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/string:41,
from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/locale_classes.h:40,
from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/ios_base.h:41,
from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/ios:42,
from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/ostream:38,
from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/iostream:39,
from foo.cpp:2:
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/new:116:41: error: declaration of ‘void operator delete(void*) noexcept’ has a different exception specifier
__attribute__((__externally_visible__));
^
In file included from foo.cpp:1:0:
./foo.h:8:6: error: from previous declaration ‘void operator delete(void*)’
void operator delete(void* p);
^
In file included from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/ext/new_allocator.h:33:0,
from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/x86_64-pc-cygwin/bits/c++allocator.h:33,
from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/allocator.h:46,
from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/string:41,
from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/locale_classes.h:40,
from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/bits/ios_base.h:41,
from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/ios:42,
from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/ostream:38,
from /usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/iostream:39,
from foo.cpp:2:
/usr/lib/gcc/x86_64-pc-cygwin/5.4.0/include/c++/new:118:41: error: declaration of ‘void operator delete [](void*) noexcept’ has a different exception specifier
__attribute__((__externally_visible__));
^
In file included from foo.cpp:1:0:
./foo.h:9:6: error: from previous declaration ‘void operator delete [](void*)’
void operator delete[](void* p);
^
Некоторые странности в этом вопросе, которые я считаю релевантными:
- Если я комментирую
#include <iostream>
вfoo.cpp
, компиляция завершается успешно - Если я прокомментирую объявления функций в
foo.h
и сохраняю их определения, вfoo.cpp
(а также сохраняя#include <iostream>
), компиляция завершается успешно.
У меня есть некоторые неопределенные подозрения; возможно, ответчики подтвердят их ответы:
- В этой ошибке упоминается
exception specifier
, поэтому я подумал, что, возможно, переопределив любой из этих операторов, я обязан переопределить весь набор своих братьев и сестер. Однако добавление объявления и определенияoperator delete(void*, const std::nothrow_t&)
не изменило ошибку компиляции. Я также не думаю, что должно быть правдой, что переопределение любого из этих операторов обязывает кодера реализовать все из них, но я ошибаюсь в этом? - Я прочитал статью за пределами StackOverflow, в которой упоминается, что эти операторы должны быть включены только в одну "блок переводов" и поэтому не должны быть в файлах заголовков. Я не понимаю, что такое единица перевода, и эта статья не объяснила, что это такое. Если это связано с этой проблемой, пожалуйста, объясните, что такое "единица перевода" и почему это требует исключения объявлений функций из файла заголовка - это кажется противоречивым всем моим предыдущим навыкам программирования на С++.
Благодарим вас за понимание.