CBFalconer said:
But that provision would force the storage of all those small
values. That is where the inefficiency comes in.
I don't follow.
For concreteness, one implementation I'm familiar with is amd64, where
structs of 8 bytes or less are returned in a register, structs of 8 to
16 bytes are returned in two registers, and larger structs are copied
into a space which is passed (invisibly) by the caller. This
convention is fixed by an ABI, which a C1x compiler would likely
conform to.
The draft standard requires a temporary object to exist, but as far as
I can tell there's no need for it to be stored in memory unless
something actually looks for it there. If we have
struct foo { long a; long b; }; /* long is 8 bytes on amd64 */
struct foo blah(void);
void qux(long);
void argle(long *);
then doing
qux(blah().a)
would not require the return value of blah() to be stored in memory at
any time. The compiler could simply move the value of blah().a from
the register where it was returned into the appropriate register to
pass it to qux(). It's the same as if you have an auto variable of
type long; unless you take its address (or perhaps declare it
volatile), the compiler is free to keep it in a register, or even
optimize it completely out of existence.
Now it also seems that under the draft standard, we can do
argle(&blah().a)
and argle will be able to dereference its argument. In this case you
are correct that some storage would be needed. But seeing as under
C99 this code apparently results in undefined behavior (as the
lifetime of the object containing the returned value from blah() isn't
long enough), you can't really say it's less efficient.
If you have something else in mind, could you give an example of a
piece of code where a compiler conforming to the draft standard would
be required to do something less efficient than a C99 compiler?
Also consider the interactions.
What interactions are you referring to?