Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Argument evaluation order between curly braces and parentheses

#include <stdlib.h>
#include <stdint.h>
#include <stdio.h>

uint32_t func() { return rand() % 10; }

struct A {
  uint32_t _x, _y, _z;
  A(uint32_t x, uint32_t y, uint32_t z) : _x(x), _y(y), _z(z) {}
};

int main() {
  A a{func(), func(), func()};
  //A a(func(), func(), func());

  printf("%d %d %d\n", a._x, a._y, a._z);
  return 0;
}

GCC 9.1 and MSVC 19.22.27905 will both print a different order when using curly braces or parentheses. Clang 8.0.0 will print the same order for both cases.

I can´t find anything in the standard about it, is it in the standard or is it up to the compiler which orders it evaluates the input argument?

like image 280
hidayat Avatar asked Dec 22 '22 21:12

hidayat


2 Answers

The order is only guaranteed for braced-init-list, [dcl.init.list]/4:

(emphasis mine)

Within the initializer-list of a braced-init-list, the initializer-clauses, including any that result from pack expansions ([temp.variadic]), are evaluated in the order in which they appear. That is, every value computation and side effect associated with a given initializer-clause is sequenced before every value computation and side effect associated with any initializer-clause that follows it in the comma-separated list of the initializer-list. [ Note: This evaluation ordering holds regardless of the semantics of the initialization; for example, it applies when the elements of the initializer-list are interpreted as arguments of a constructor call, even though ordinarily there are no sequencing constraints on the arguments of a call. — end note ]

On the other hand, order of evaluation of arguments in a function call is unspecified.

unspecified behavior - the behavior of the program varies between implementations and the conforming implementation is not required to document the effects of each behavior. For example, order of evaluation, whether identical string literals are distinct, the amount of array allocation overhead, etc. Each unspecified behavior results in one of a set of valid results.

like image 160
songyuanyao Avatar answered Jun 03 '23 10:06

songyuanyao


It seems that Clang evaluates arguments in this declaration

A a( func(), func(), func() );

from left to right. While the other compilers evaluate them in the order from right to left.

The order of the evaluation of arguments is unspecified.

As for the curly braces then the evaluation is strictly determined from left to right and evaluation of each expression is sequenced.

like image 21
Vlad from Moscow Avatar answered Jun 03 '23 11:06

Vlad from Moscow