M
Marc
Hello,
the example wikipedia gives for return value optimization (copy elision)
is the following:
#include <iostream>
struct C
{
C() {}
C(const C&) { std::cout << "A copy was made.\n"; }
};
C f()
{
return C();
}
int main()
{
std::cout << "Hello World!\n";
C obj = f();
}
which, with the 4 compilers I tried, doesn't perform any copy (nice!).
Now if I create a wrapper for C:
struct D : C
{
D(){}
D(int):C(f()){}
D(C const& c):C(c){}
// it doesn't matter if I write D(C c):C(c){} instead
};
int main()
{
D obj = 3; // no copy (except with sunpro)
D obj = f(); // 1 COPY :-(
}
I am trying to understand if the compiler could (legally and
technically) avoid that copy. I believe it would be legal:
"when a temporary class object that has not been bound to a reference
(12.2) would be copied to a class object with the same cv-unqualified
type, the copy operation can be omitted by constructing the temporary
object directly into the target of the omitted copy"
but, as opposed to the regular RVO optimization, the compiler first
needs to inline the call to D: to have enough information to elide the
copy, which is too late with the organization of most compilers.
This means that if I really want to limit copying, I need to make sure
classes like D have "emplace"-like constructors.
Is my understanding correct? Any idea how hard it would be to add this
kind of optimization to a compiler? (for instance some heuristic early
inlining of things that are not copy/move constructors, before the copy
elision checks, possibly helped by a hard_inline attribute)
the example wikipedia gives for return value optimization (copy elision)
is the following:
#include <iostream>
struct C
{
C() {}
C(const C&) { std::cout << "A copy was made.\n"; }
};
C f()
{
return C();
}
int main()
{
std::cout << "Hello World!\n";
C obj = f();
}
which, with the 4 compilers I tried, doesn't perform any copy (nice!).
Now if I create a wrapper for C:
struct D : C
{
D(){}
D(int):C(f()){}
D(C const& c):C(c){}
// it doesn't matter if I write D(C c):C(c){} instead
};
int main()
{
D obj = 3; // no copy (except with sunpro)
D obj = f(); // 1 COPY :-(
}
I am trying to understand if the compiler could (legally and
technically) avoid that copy. I believe it would be legal:
"when a temporary class object that has not been bound to a reference
(12.2) would be copied to a class object with the same cv-unqualified
type, the copy operation can be omitted by constructing the temporary
object directly into the target of the omitted copy"
but, as opposed to the regular RVO optimization, the compiler first
needs to inline the call to D: to have enough information to elide the
copy, which is too late with the organization of most compilers.
This means that if I really want to limit copying, I need to make sure
classes like D have "emplace"-like constructors.
Is my understanding correct? Any idea how hard it would be to add this
kind of optimization to a compiler? (for instance some heuristic early
inlining of things that are not copy/move constructors, before the copy
elision checks, possibly helped by a hard_inline attribute)