首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >递增在初始化器列表中使用了两次的变量-未定义的行为?

递增在初始化器列表中使用了两次的变量-未定义的行为?
EN

Stack Overflow用户
提问于 2016-09-06 11:04:14
回答 2查看 861关注 0票数 17

编辑:尚未回答-链接的问题是关于普通的r值,初始化器列表是一个单独的概念,如果相关的话。

这条语句是定义良好的,还是在初始化器列表中使用前缀增量运算符,在列表中出现两次的变量,未定义的行为?

代码语言:javascript
复制
struct T t = { i, ++i };

我对ANSI最感兴趣,但了解其他版本的C和/或C++是否不同也很有用。如果类似如下的构造是合法的:

代码语言:javascript
复制
struct T t = { i, i++ };

struct T t = { ++i, ++i };

struct T t = { i++, ++i };

struct T t = { i++, i++ };
EN

回答 2

Stack Overflow用户

发布于 2016-09-06 11:25:15

C++11和更高版本的

对于list initialization,这种行为是定义良好的。根据sequenced-before rules (从C++11开始):

10)在列表初始化中,给定初始化器子句的每个值计算和副作用都是在与它后面的任何初始化器子句相关的每个值计算和副作用之前排序的,该初始化器子句后面是用括号括起来的逗号分隔的初始化器列表。

因此,对于struct T t = { i, ++i };,将首先评估i,然后再评估++i,顺序是明确定义的。其他的样本也都没问题。

引用自C++标准$8.6.4/4 List-initialization [dcl.init.list]

(强调我的)

在带括号的初始化列表的初始化器列表中,初始化器子句,包括任何由包扩展(temp.variadic)产生的子句,都按照它们出现的顺序进行计算。也就是说,在初始化器列表的逗号分隔列表中,与给定的初始化器子句相关联的每个值计算和副作用在与它后面的任何初始化器子句相关联的每个值计算和副作用之前被排序。注意:无论初始化的语义如何,这种求值顺序都有效;例如,当初始化器列表的元素被解释为构造函数调用的参数时,即使通常对调用的参数没有排序约束,它也适用。-结束注释

票数 15
EN

Stack Overflow用户

发布于 2016-09-06 11:26:55

在C11中,所有这些初始化的行为都不是未定义的。参见6.7.9/23:

初始化列表表达式的求值相对于彼此是不确定的排序,因此任何副作用发生的顺序是未指定的。

术语不确定排序的定义如下(5.1.2.3):

当A在B之前或之后排序时,

评估A和B的排序是不确定的,但未指定是哪一个。

在C99中,所使用的语言没有明确地表述为是相同的情况,还是未定义的行为。在C89中根本没有提到这个问题,所以我们可能应该假设在C89中这些都是未定义的。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39340030

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档