大括号和括号之间的参数计算顺序

Argument evaluation order between curly braces and parentheses

本文关键字:计算 顺序 参数 之间      更新时间:2023-10-16
#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 %dn", a._x, a._y, a._z);
return 0;
}

使用大括号或括号时,GCC 9.1MSVC 19.22.27905都将打印不同的顺序。 对于这两种情况,Clang 8.0.0将打印相同的订单。

我在标准中找不到有关它的任何内容,是在标准中还是由编译器对输入参数进行排序?

该顺序仅保证用于大括号的 init-list [dcl.init.list]/4:

(强调我的(

在大括号初始化列表的初始值设定项列表中,初始值设定项子句(包括由包扩展([temp.variadic](产生的任何子句(将按照其出现的顺序进行评估。也就是说,与给定初始值设定项子句关联的每个值计算和副作用在初始值设定项列表的逗号分隔列表中与它后面的任何初始值设定项子句关联的每个值计算和副作用之前进行排序。[注意:无论初始化的语义如何,此计算顺序都成立;例如,当初始值设定项列表的元素被解释为构造函数调用的参数时,它适用,即使通常调用的参数没有排序约束。

另一方面,函数调用中参数的计算顺序未指定。

未指定的行为- 程序的行为因实现而异,并且不需要符合实现来记录每个行为的效果。例如,计算顺序、相同的字符串文本是否不同、数组分配开销量等。每个未指定的行为都会导致一组有效结果之一。

似乎 Clang 评估了此声明中的参数

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

从左到右。而其他编译器则按从右到左的顺序评估它们。

参数的计算顺序未指定。

至于大括号,则严格从左到右确定评估,并对每个表达式的评估进行排序。