I am writing a custom memory allocator. If possible, I want to make object creation function like this to abstract creation procedure completely.
template<typename T>
class CustomCreator
{
virtual T& createObject(T value) __attribute__((always_inline))
{
T* ptr = (T*)customAlloc();
new (ptr) T(value);
return *ptr;
}
}
But this causes copying. Is there a way to force to eliminate copying in this case?
Here's my current testing code.
#include <iostream>
struct AA
{
inline static void test(AA aa) __attribute__((always_inline))
{
AA* ptr = new AA(aa);
delete ptr;
}
AA(AA const& aa)
{
printf("COPY!\n");
}
AA(int v)
{
printf("CTOR!\n");
}
};
int main(int argc, const char * argv[])
{
AA::test(AA(77));
return 0;
}
I tried to pass the value
as T&
, T const&
, T&&
, T const&&
, but it still copies.
I expected optimizer will eliminate function frame, so the function parameter can be deduced into an R-value, but I still see COPY!
message.
I also tried C++11 forwarding template, but I couldn't use it because it cannot be a virtual function.
My compiler is Clang included in Xcode. (clang-425.0.28) And optimization level is set to -Os -flto
.
Update (for later reference)
I wrote extra tests, and checked generated LLVM IR with clang -Os -flto -S -emit-llvm -std=c++11 -stdlib=libc++ main.cpp;
options. What I could observe are: (1) function frames always can be get eliminated. (2) if large object (4096 byte) passed by value, it didn't get eliminated. (3) Passing r-value reference using std::move
works well. (4) if I don't make move-constructor, compiler mostly fall back to copy-constructor.