0

Up to Order of evaluation in C++ function parameters and What are the evaluation order guarantees introduced by C++17? are delegate ctors affected by evaluation order?

struct A
{
    A( int a, int b ) : mA(a), mB(b) {}
    A( std::vector<u8>::const_iterator& aBuffer ) :
        A( CreateIntFromBuffer(aBuffer), CreateIntFromBuffer(aBuffer) ) {}
};

I need to repeat-my-self using mA and mB names another time?

There is some difference between the c++XX standards?

Isaac Pascual
  • 382
  • 1
  • 12

1 Answers1

3

[class.base.init]

7 The expression-list or braced-init-list in a mem-initializer is used to initialize the designated subobject (or, in the case of a delegating constructor, the complete class object) according to the initialization rules of [dcl.init] for direct-initialization.

[dcl.init]

19 If the initializer is a parenthesized expression-list, the expressions are evaluated in the order specified for function calls.

Given the above two paragraph, I would conclude that the order of evaluation in...

A( CreateIntFromBuffer(aBuffer), CreateIntFromBuffer(aBuffer) )

... of the two calls is unspecified (other than not interleaving). So you cannot rely on the left call completing before the right call, or vice-versa.

One could force a left to right evaluation order by using a brace init list like...

A{ CreateIntFromBuffer(aBuffer), CreateIntFromBuffer(aBuffer) }

... but I would call it at least a somewhat arcane use of brace initialization. Consider refactoring.

In a pinch, one could use a named function that returns an A, and delegate to the copy/move constructor:

struct A
{
    static A makeA(std::vector<u8>::const_iterator& aBuffer) {
        int a = CreateIntFromBuffer(aBuffer);
        int b = CreateIntFromBuffer(aBuffer);
        return A(a,b);
    }
    A( int a, int b ) : mA(a), mB(b) {}
    A( std::vector<u8>::const_iterator& aBuffer ) : A(makeA(aBuffer)) {}
};

Thanks to guaranteed copy elision, this won't actually involve any copies.

StoryTeller - Unslander Monica
  • 148,497
  • 21
  • 320
  • 399