简体   繁体   中英

Argument evaluation order between chained static function calls

I am curious why there is a difference in the argument evaluation order between chained static functions and member functions. From the answers at this question I can see it is unspecified what the argument evaluation order is between such chained function calls. Take for example the following snippet:

#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;
}

In the case of GCC 4.6.2 and CL 15.00.30729.01 (MSVC 9) the resulting output is for me

5 5 5
3 4 5

However, I was wondering if there is any reason in the specification or if it is otherwise known why the static function are evaluated left-to-right (with their arguments), and for the non-static function all the arguments first (right-to-left from what I've seen in other tests).

The reason I'm asking this is because I first noticed this difference in behavior when trying to get similar behavior in C (using a struct and a function pointer) and failed. I strongly suspect this is some optimization implemented both in GCC and MSVC for member functions, but I hope someone here can shed a little more light on this.

Edit:
I forgot to mention one crucial bit of information which strikes me as odd: GCC will only warn on unspecified behavior on the chained non-static function, but not the static functions:

a.cpp: In function 'int main(int, char**)':
a.cpp:18:45: warning: operation on 'x' may be undefined [-Wsequence-point]

GCC is not obligated to provide such warnings so it could miss the second expression, but this is what leads me to believe something interesting is going on.

No reason. Like you say, the order is unspecified by the language.

One reason for using right to left order is that functions with a variable number of parameters, like printf , will then always have the first parameter on top. Otherwise it doesn't matter.

Your code has undefined behavior, but I suppose you know that. Also, you could easily see a difference depending on optimization flags. But in this case, one likely reason is that the non-static functions require three arguments, including the results of the previous call, where as the static functions only require two, and the results of the previous call are ignored.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM