2012年(158)
分类: C/C++
2012-11-26 15:20:37
复杂形态下参数的入栈顺序
只是简单测试了一下,测试用例不全。欢迎大家从C/C++标准的规定上讲讲!
用的是仿函数,普通函数也测试过一部分
编译器用的有VC6,和MinGW32(版本不去查了,我机子里装了太多版本的mingw,自己都不知道实际起作用的是哪个)
问题的引入:
形如 cout << a << b;
的表达式,是先执行a还是先执行b?(不是问先输出哪个)
为了弄清这个问题,需要先知道参数的入栈顺序。
测试代码如下:
#include
using namespace std;
// 这个类用于在参数压栈时立即显示
struct param
{
explicit param( int n ) :
num_(n)
{
cout << "construct " << num_ <<
endl;
}
int value() const
{
return num_;
}
private:
int num_;
friend ostream& operator<<( ostream& os, const param& p
);
};
ostream& operator<<( ostream& os, const param& p
)
{
return os << "construct " << p.num_;
}
struct foo1
{
const foo1& operator()( const param& p )
const
{
cout << p.value() << endl;
return *this;
}
void bar( const param& p ) const
{
cout <<
p.value() << endl;
}
};
const foo1& foo2( const foo1& f1, const param& p )
{
return f1( p );
}
int main()
{
foo1()( param(0) )( param(1) );
foo2( foo2(foo1(),param(0)), param(1) );
foo1()( param(0) ).bar( param(1) );
return 0;
}
输出:
construct 1
construct 0
0
1
construct 1
construct
0
0
1
construct 1
construct 0
0
1
结论:(当然,入栈顺序和平台编译器相关)
对于表达式 function( 参数1 )( 参数2 ),参数2先入栈
对于表达式
function( function(参数1), 参数2 ),也是参数2先入栈
对于表达式 function( 参数1 ).mem_fun( 参数2
),同样是参数2先入栈
对于 cout << 内建型别对象1 << 内建型别对象2
实质就是 cout.operator<<(
内建型别对象1 ).operator<<( 内建型别对象2 ),endl等manipulators也是这样
对于 cout << 自定义型别对象1 << 自定义型别对象2
实质就是 operator<<(
operator<<(cout,自定义型别对象1), 自定义型别对象2 )
所以当写出 cout << a() << b()
类似代码时,如果a和b的调用会互相影响时,千万不要因为先输出a()就认为a()在b()前被执行。
当然,按照C/C++标准,在同一个表达式中不应该对同一个变量/状态作多次修改,这是一个“未定义”行为,即平常所见的
++i + ++i;
问题在于 ++i + ++i 见多了所以不会犯错误,但换一种形式如 cout << a << b
时则容易犯错。