Foo
below is a primitive type instead (e.g. int
)?Foo
?Returning by value:
inline Foo getMyFooValue() { return myFoo; }
Foo foo = getMyFooValue();
Returning by reference:
inline const Foo &getMyFooReference() { return myFoo; }
Foo foo = getMyFooReference();
Modifying in place:
inline void getMyFooInPlace(Foo &theirFoo) { theirFoo = myFoo; }
Foo foo;
getMyFooInPlace(foo);
Are the following functions guaranteed to have the same implementation (i.e. object code)?
No, the language only specifies behaviour, not code generation, so it's up to the compiler whether two pieces of code with equivalent behaviour produce the same object code.
Does this change if
Foo
below is a primitive type instead (e.g.int
)?
If it is (or, more generally, if it's trivially copyable), then all three have the same behaviour, so can be expected to produce similar code.
If it's a non-trivial class type, then it depends on what the class's special functions do. Each calls these functions in slightly different ways:
foo
with that, then destroy the temporary (calling the destructor); but more likely it will elide the temporary, becoming equivalent to the second.foo
(calling the copy constructor)foo
(calling the default constructor), then copy-assign to it (calling the assignment operator).So whether or not they are equivalent depends on whether default-initialisation and copy-assignment has equivalent behaviour to copy-initialisation, and (perhaps) whether creating and destroying a temporary has side effects. If they are equivalent, then you'll probably get similar code.
Does this change with the size of
Foo
?
No the size is irrelevant. What matters is whether it's trivial (so that both copy initialisation and copy assignment simply copy bytes) or non-trivial (so that they call user-defined functions, which might or might not be equivalent to each other).