Reputation: 76859
The current C++ standard draft in [class.temporary]/7 contains the phrase
a temporary object other than a function parameter object
I was under the impression that function parameter objects are not temporary objects. However, this phrase was added relatively recently. So am I mistaken or misunderstanding the context?
Upvotes: 10
Views: 550
Reputation: 12708
Parameter objects that are passed by value are temporary objects in the sense that they are created on function call, and destroyed on function return. They are described so in Stroustrup language definition, so I think this has not changed over time. Of course, object parameter that are pased by reference, the parameter is, itself, a reference to an existent object and will not be temporary in the scope of the function call.
Upvotes: 0
Reputation: 119562
An example in [stmt.ranged] illustrates CWG's intent:
using T = std::list<int>;
const T& f1(const T& t) { return t; }
const T& f2(T t) { return t; }
T g();
void foo() {
for (auto e : f1(g())) {} // OK, lifetime of return value of g() extended
for (auto e : f2(g())) {} // undefined behavior
}
So the "other than a function parameter object" wording is referring to the parameter t
of f2
.
I think the OP is right that this isn't actually a temporary object; it doesn't fall under any of the categories mentioned in [class.temporary]/1. However, on some implementations a function parameter object has temporary-like characteristics in that it might be destroyed at the end of the full-expression containing the call, rather than at the point you would expect for a block variable. And I think that was the case that CWG was trying to address here.
Upvotes: 5
Reputation: 40009
The arguments passed to function parameters aren't always temporary. They are only temporary in a special case:
When an object of class type
X
is passed to or returned from a function, ifX
has at least one eligible copy or move constructor ([special]), each such constructor is trivial, and the destructor ofX
is either trivial or deleted, implementations are permitted to create a temporary object to hold the function parameter or result object. The temporary object is constructed from the function argument or return value, respectively, and the function's parameter or return object is initialized as if by using the eligible trivial constructor to copy the temporary (even if that constructor is inaccessible or would not be selected by overload resolution to perform a copy or move of the object).[Note 4: This latitude is granted to allow objects of class type to be passed to or returned from functions in registers. — end note]
Note that the condition is quite complicated here, and this is deliberate. Instead of saying that all trivially copyable types are passed as a temporary object, the condition ignores the copy/move assignment operators and mirrors the requirement of "ABI-triviality" in the System-V ABI, i.e. the requirements for pass-by-register.
Outside of this special case, function parameter objects are not temporary objects. One important distinction is that temporary objects are always destroyed at the end of the surrounding full-expression ([class.temporary] p4), but function parameter objects can be destroyed by the callee ([expr.call] p6).
Note that this paragraph states that the function parameter object isn't the temporary object but a trivial copy of it, and p7 suggests that the function parameter object itself could be temporary. I believe this to be an editorial mistake in p7.
Upvotes: 1
Reputation: 17072
Scrolling up to [class.temporary]/3:
implementations are permitted to create a temporary object to hold the function parameter
Not all parameter objects are temporary objects, but some are allowed to be.
Upvotes: 2