Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order of functions calls

Tags:

c++

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());
like image 661
FrozenHeart Avatar asked Dec 08 '25 07:12

FrozenHeart


1 Answers

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.

like image 73
SergeyA Avatar answered Dec 09 '25 20:12

SergeyA