The example code is quite simple, with a simple custom allocator and a std::vector
:
#include <cstdlib>
#include <vector>
namespace {
template <typename T>
class MyAllocator {
public:
typedef T value_type;
T* allocate(std::size_t n) {
T* p = static_cast<T*>(std::malloc(sizeof(T) * n));
if (p == nullptr) throw std::bad_alloc();
return p;
}
void deallocate(T* p, std::size_t) {
std::free(p);
}
};
void bar() {
std::vector<int, MyAllocator<int>> v;
v.push_back(49);
}
} // anonymous namespace
int main(int, char**) {
::bar();
return 0;
}
Clang 6.0.0
can "full optimise" the code removing the allocation. GodBolt Here:
main: # @main
xor eax, eax
ret
Is that legal? Can a std::malloc
be discarded by the optimizer, even if there is a throw
flow?
Note that GCC
gives me the expected result.
Bonus Question: if I remove the anonymous namespace the compiler produces 150 lines of assembly code, why?