C#中GiveElement方法返回元组的跨环境行为一致性及是否属未指定行为?
关于C#元组初始化中表达式执行顺序的问题
问题背景
给出以下C#代码:
int counter = 0; int[] array = new int[] { 1, 2, 3, 4, 5 }; (int, int) GiveElement() => (array[++counter], array[counter]);
在.NET 7环境(如dotnetfiddle)中执行后返回元组(2,2),但ChatGPT给出的结果是(2,1)。现咨询两个问题:
- 该方法的返回值顺序是否在所有编译器中保持一致,即
counter始终先递增用于第一个元素,第二个元素也取相同值? - 该行为是否类似C++中的“unspecified behaviour”(未指定行为)?
解答
- 执行顺序的一致性:C#语言规范明确要求,元组初始化器中的元素表达式必须从左到右依次求值。对于上述代码,
array[++counter]会先执行:counter从0自增为1,取值array[1]即2;随后执行array[counter],此时counter已经是1,取值同样为array[1]即2。所有符合C#规范的编译器都会遵循这个规则,返回结果必然是(2,2),不存在跨编译器的行为差异。 - 与C++未指定行为的区别:该行为和C中的未指定行为完全不同。C中部分表达式的求值顺序未被规范约束,编译器可自行选择执行顺序;而C#对这类表达式的求值顺序有严格、明确的规定,属于确定性行为,不存在歧义或编译器自由选择的空间。
- 补充:ChatGPT给出的错误结果是因为未准确遵循C#的规范细节,属于生成内容的错误,不能作为参考。
内容的提问来源于stack exchange,提问作者PiotrBzdrega
相关产品推荐
相关产品推荐

