Is it guaranteed that the make_string object will be constructed before the call to GetLastError function in the following code:
class make_string
{
public:
template <typename T>
make_string& operator<<(const T& arg)
{
_stream << arg;
return *this;
}
operator std::string() const
{
return _stream.str();
}
protected:
std::ostringstream _stream;
};
// Usage
foo(make_string() << GetLastError());
No, it is not guranteed. make_string() << GetLastError() is semantically equivalent to the function call operator<<( make_string(), GetLastError() ), and order of evaluation of function arguments is unspecified.
So, the compiler can first create an instance of make_string, then call GetLastError(), and then call a member function of said make_string object, or it could first call GetLastError(), then create an instance, and then call the member function. In my experience, the second outcome is more likely.
EDIT
There is also an interesting question raised couple of times in comments, which I believe is worth addressing.
The claim is, that since operator<< is a member function, the whole statement is semantically the same as
make_string().operator<<(GetLastError());
This claim is, indeed, true. However, there is no sequencing in the above statement! What happens first - GetLastError() call or make_sequence constructor is undefined because of lack of sequencing here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With