Consider safety software, where dynamic allocation in general is disallowed and exceptions are disallowed. Dynamic allocation is allowed only when class explicity defines operator new
and delete
. Using operator new
for others class should cause compilation failure.
The simplest way to cause compilation failure in described situation is to remove global new operator:
void* operator new(std::size_t) = delete;
On the one hand this cause side effects with standard library. For example including <array>
propagates inclusion to <new_allocator>
by <stdexcept>
. <new_allocator>
uses ::new
operator and this cause build fail even when You don't want to use exception and memory allocation. According to Scoot Meyers <array>
should be bare metal friendly.
On the other hand this cause error with compiler built-in operator
src/main.cpp:91:31: error: deleted definition of 'void* operator new(std::size_t)'
void* operator new(std::size_t) = delete; ^
<built-in>: note: previous declaration of 'void* operator new(std::size_t)'
Is there any solution to ban ::new
and use <array>
?
Is there any solution to ban ::new
globally at all?
If you use GCC and GNU LD, then I think you can just add
--wrap=malloc
to your linker flags. As global::new
usesmalloc()
internally, all calls tomalloc()
in your application will be replaced with__wrap_malloc()
. If this function is undefined, then the linking will fail.Another, possibly simpler option, is to add
ASSERT(DEFINED(malloc) == 0, "Dynamic allocation used!");
to your linker script. This will assert thatmalloc()
is not defined.Neither of these options protect you from redefining global
::new
to use some other form of global allocation. You could do the same for global symbol::new
in the linker script, but its name is mangled (in here_Znwj
), so this will be a little strange...