C++ 链式静态函数调用之间的参数求值顺序
我很好奇为什么链式静态函数和成员函数的参数求值顺序不同。从在的答案中,我可以看出,在这样的链式函数调用之间,参数的求值顺序是不明确的。以以下代码段为例:C++ 链式静态函数调用之间的参数求值顺序,c++,static,chaining,sequence-points,C++,Static,Chaining,Sequence Points,我很好奇为什么链式静态函数和成员函数的参数求值顺序不同。从在的答案中,我可以看出,在这样的链式函数调用之间,参数的求值顺序是不明确的。以以下代码段为例: #include <iostream> class test { public: static test& chain_s(test& t, int i) { std::cout << i << " "; return t; } tes
#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;
}
但是,我想知道规范中是否有任何原因,或者是否知道为什么静态函数是从左到右求值的(带参数),而对于非静态函数,所有参数都是先求值的(从其他测试中看到的从右到左)
我问这个问题的原因是,当我试图在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]
GCC没有义务提供这样的警告,因此它可能会错过第二个表达式,但这让我相信发生了一些有趣的事情。没有理由。正如您所说,语言未指定顺序
使用从右到左顺序的一个原因是,参数数量可变的函数(如
printf
)总是将第一个参数放在顶部。否则就没关系了。您的代码有未定义的行为,但我想您知道这一点。也,
根据优化标志的不同,您很容易看到差异。但是
在这种情况下,一个可能的原因是非静态函数需要
三个参数,包括上一次调用的结果,其中
静态函数只需要两个,并且是前一个函数的结果
调用被忽略。当然,在您编写的任何代码中,这样的事情都应该是无关的……是的,但我想知道为什么有些代码是错误的,但在类似的情况下却不会产生警告。我忘了问编译器输出消息为何不同,对此有何看法?这也是导致整个问题的原因。即使使用
printf
,编译器也可以按任意顺序计算参数,甚至可以交错计算。在基于堆栈的机器上,第一个参数很可能是最后一个推送的参数,但编译器也很有可能只是在堆栈上保留必要的空间,并使用sp relative addressing将每个参数存储在它所属的位置。并且以任何它认为方便的顺序这样做。
a.cpp: In function 'int main(int, char**)':
a.cpp:18:45: warning: operation on 'x' may be undefined [-Wsequence-point]