为啥我的程序从右到左评估参数?

Posted

技术标签:

【中文标题】为啥我的程序从右到左评估参数?【英文标题】:Why is my program evaluating arguments right-to-left?为什么我的程序从右到左评估参数? 【发布时间】:2019-10-26 19:01:26 【问题描述】:

我正在学习 C,所以我尝试了下面的代码,得到的输出是 7,6 而不是 6,7。为什么?

#include <stdio.h>
int f1(int);
void main()

    int b = 5;
    printf("%d,%d", f1(b), f1(b));

int f1(int b)

    static int n = 5;
    n++;
    return n;

【问题讨论】:

【参考方案1】:

函数参数的计算顺序在 C 中是未指定的。(注意这里没有未定义的行为;例如,不允许同时计算参数。)

通常,参数的评估是从右到左,或者从左到右。

根据经验,如果该函数有副作用(就像您的情况一样),或者如果您两次传递相同的参数以允许在调用要修改的站点(例如传递一个指针)。

【讨论】:

感谢您的回复我能找到更多关于这个主题的详细文章吗? 只是谷歌我在答案中提到的一些术语。 @Nico238 "3.4.4 1 未指定的行为 使用未指定的值,或本国际标准提供两种或多种可能性且没有进一步要求的其他行为在任何情况下选择。2 示例未指定行为的一个示例是评估函数参数的顺序。不同于“3.4.3 1 未定义的行为”。 @Nico238:C 标准明确定义“未定义行为”是指标准对没有要求的行为。如果在某些情况下,行为施加了部分而非全部要求,例如要求单独执行评估(根本不交错)但以任何顺序执行,则这不是标准定义的未定义行为。 @Nico238 未定义行为和未指定行为都是正式术语,它们是不同的。 Undefined, unspecified and implementation-defined behavior【参考方案2】:

https://en.cppreference.com/w/c/language/eval_order

在C11之前,你必须遵守规则(2)

There is a sequence point after evaluation of the first (left) operand and 
before evaluation of the second (right) operand of the following binary 
operators: && (logical AND), || (logical OR), and , (comma).

因为参数在 C11 之前被认为是用逗号分隔的。这不是最优的,因为参数在某些平台上是从右向左推送的。因此,C11 添加了规则 (12) 使其未指定。

A function call that is not sequenced before or sequenced after another 
function call is indeterminately sequenced (CPU instructions that 
constitute different function calls cannot be interleaved, even if the 
functions are inlined)

即使是 C99 指定的初始值设定项,仍然会回到规则 (2),其中相对于逗号运算符,较早(左)的初始值设定项在较晚(右)的初始值设定项之前被解析。也就是说,直到 C11 添加规则 (13) 使其未指定。

In initialization list expressions, all evaluations are indeterminately 
sequenced

换句话说,在规则 (12) 和规则 (13) 之前,规则 (2) 中的逗号运算符是指定的行为。规则 (2) 导致无法在某些平台上优化的低效代码。如果结构成员或函数参数的数量超过某个阈值,则没有足够的寄存器。也就是说,“注册压力”成为一个问题。

从历史上看,聚合类型初始值设定项和函数参数回退到逗号运算符。在 C11 中,他们特别添加了在这些聚合类型初始化程序和函数参数中的逗号不是“逗号运算符”的定义,因此规则 (12) 和规则 (13) 有意义,并且规则 (2) 不适用。

【讨论】:

以上是关于为啥我的程序从右到左评估参数?的主要内容,如果未能解决你的问题,请参考以下文章

目标c:向Notes添加从右到左的语言

移动按钮从右到左动画iOS - swift

如果操作系统低于 Win10,GraphicsPath AddString 对使用从右到左语言时的字体支持不够

如何在从右到左的位置(视差)连续移动 Sprite?

Android:如何处理从右到左的滑动手势

从右到左 SnackBar