Chinaunix首页 | 论坛 | 博客
  • 博客访问: 988428
  • 博文数量: 158
  • 博客积分: 4380
  • 博客等级: 上校
  • 技术积分: 2367
  • 用 户 组: 普通用户
  • 注册时间: 2006-09-21 10:45
文章分类

全部博文(158)

文章存档

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 时则容易犯错。

阅读(1156) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

网友评论2012-11-26 15:21:29

周星星
怎么有点像64bits平台上的表现:)
要么就是用了__fastcall修饰,且前四个参数占用的字节数特别少;
更可能的是,你用那个编译器是为你那个CPU特俗设计过的

网友评论2012-11-26 15:21:21

zhanggf001
不知道是不是特殊的设计,在blackfin平台上的gcc,小于等于4个参数是不入栈的,直接用寄存器,超过4个的参数才入栈。所以函数参数不要超过4个。