Yes, this could work for simple cases, but this breaks down pretty quickly:
void checkFoo(const Foo&);
Foo getFoo();
void example() {
std::vector<Foo> vec;
Foo foo = getFoo();
if (checkFoo(foo)) {
// *We* know that checkFoo() does not store a
// reference to 'foo' but the compiler does not
// know this. Therefore it cannot automatically
// move 'foo' into the std::vector.
vec.push_back(std::move(foo));
}
}
The fundamental problem is that C++ does not track object lifetimes. You would end up with a system where the compiler would move objects only under certain circumstances, which would be very hard to reason about.
Ah, you are right. It theoretically should be able to do it, but even with -flto, there are likely cases, where it doesn't. It is less of a problem with C, since you explicitly tell the compiler, whether you want things to get passed as value or pointer. Also I typically annotate ownership, so it it easy to forget that the compiler doesn't actually knows this. This is a weird limitation, there should be just a parameter attribute to do that.