链式静态函数调用之间的参数评估顺序

时间:2012-01-17 19:20:42

标签: c++ static chaining sequence-points

我很好奇为什么链式静态函数和成员函数之间的参数评估顺序存在差异。从this question的答案我可以看出,未指定这种链式函数调用之间的参数评估顺序是什么。以下面的代码段为例:

#include <iostream>
class test {
public:
    static test& chain_s(test& t, int i) {
        std::cout << i << " ";
        return t;
    }

    test& chain(test& t, int i) {
        std::cout << i << " ";
        return *this;
    }
};

int main(int, char**) {
    int x = 2;
    test t;
    t.chain(t,++x).chain(t,++x).chain(t,++x);
    x = 2; std::cout << std::endl;
    t.chain_s(t,++x).chain_s(t,++x).chain_s(t,++x);

    return 0;
}

对于GCC 4.6.2和CL 15.00.30729.01(MSVC 9),结果输出是给我的

5 5 5
3 4 5

但是,我想知道在规范中是否有任何原因,或者是否知道为什么静态函数从左到右(带有它们的参数)被评估,而对于非静态函数,所有参数都是第一个(从我在其他测试中看到的从右到左)。

我问这个的原因是因为我在尝试在C中使用类似行为(使用结构和函数指针)并且失败时首先注意到这种行为上的差异。我强烈怀疑这是在GCC和MSVC中为成员函数实现的一些优化,但我希望有人能够对此有所了解。

修改
我忘了提到一个令我感到奇怪的重要信息:GCC只会警告链式非静态函数的未指定行为,而不是静态函数:

a.cpp: In function 'int main(int, char**)':
a.cpp:18:45: warning: operation on 'x' may be undefined [-Wsequence-point]
海湾合作委员会没有义务提供这样的警告,因此它可能会错过第二个表达,但这使我相信一些有趣的事情正在发生。

2 个答案:

答案 0 :(得分:2)

没理由。就像你说的那样,订单没有被语言指定。

使用从右到左顺序的一个原因是具有可变数量参数的函数(如printf)将始终具有顶部的第一个参数。否则没关系。

答案 1 :(得分:2)

您的代码有未定义的行为,但我想您知道这一点。也, 根据优化标记,您可以轻松看到差异。但 在这种情况下,一个可能的原因是非静态函数需要 三个参数,包括前一个调用的结果,其中as 静态函数只需要两个,而前一个的结果 呼叫被忽略。