First:
You expected the optimizer to eliminate the function frame, but it can't, because (1) that function isn't a valid case for RVO to cheat and skip the copy constructor entirely, and (2) Your function has side effects. Namely, writing copy
to the screen. So the optimizer can't optimize out the copy, because the code says it must write copy
out twice. What I would do is remove the printf
call, and check the assembly. Most likely, if it's simple, it is being optimized out.
Second:
If the members copy constructors can have side effects (such as allocating memory), then most likely you're right that it isn't being optimized out. However, you can tell it to move members rather than copying them, which is probably what you expected. For this to work you'll need to make sure your class has a move constructor alongside your copy constructor.
inline static void test(AA aa) __attribute__((always_inline))
{
AA* ptr = new AA(std::move(aa));
delete ptr;
}
Third:
In reality, even that isn't really what you want. What you probably want is something more like perfect forwarding, which will just directly pass the parameters to the constructor without making copies of ANYTHING. This means even with the optimizer disabled entirely, your code is still avoiding copies. (Note that this may not apply to your situation, templates cannot be virtual
like this, unless it's specialized)
template<class ...types>
inline static void test(types&&... values) __attribute__((always_inline))
{
AA* ptr = new AA(std::forward<types>(values)...);
delete ptr;
}