专业编程基础技术教程

网站首页 > 基础教程 正文

C++ 函数调用时的参数传递方法

ccvgpt 2025-01-15 11:14:52 基础教程 1 ℃

C++语言的函数调用

在编译后的ELF文件中,不论是C++函数还是C函数,甚至是汇编语言函数,它们之间没有任何区别。但是,C++函数在编译时会经过函数名变换(mangle)。例如,对于如下C++函数func:

class foo {

C++ 函数调用时的参数传递方法

public:

void func(int x, int y);

};

函数foo::func在ELF文件中被变换成下面的符号(mangle之后的符号名依赖于具体的实现):

# nm foo | grep foo

0000000000400508 T _ZN3foo4funcEii

另外,要从被mangle后的符号(mangled synbol)中恢复源代码中的函数原型(即进行demangle),可以使用c++filt命令(或者 nm的-C选项):

# nm foo | grep foo | c++filt

0000000000400508 T foo::func(int, int)

或者:

# nm -C foo | grep foo

0000000000400508 T foo::func(int, int)

C++函数foo::func被调用时,传递的参数比原型声明的参数多一个this指针:

void func(class foo *this, int x, int y);


在x86_64中查看参数

要查看参数的值,先用-g选项编译程序,然后用GDB运行程序,设置断点,查看寄存器:

class foo {
public:
void func(int x, int y);
};

foo::func(int x, int y)
{
    printf("func");
}

int main()
{
    foo f;
    f.func(5, 1);
}

# gdb ./foo

(gdb) break *_ZN3foo4funcEii

(gdb) run

此时程序暂停在foo::func函数

(gdb) info register

...

rdx 0x1 1

rsi 0x5 5

rdi 0x7fffa34c3ab0 140735933070000

...

以上可见,rdi rsi rdx 分别为参数:对象指针、参数x、参数y。


在i386中查看参数

i386中参数基本上通过栈来传递。

要查看参数的值,先用-g选项编译程序,然后用GDB运行程序,设置断点,查看栈:

# gdb ./foo

(gdb) break *_ZN3foo4funcEii

(gdb) run

此时程序暂停在foo::func函数

(gdb) x/3 $esp+4

0xbf9874e0: 0xbf9874fc 0x00000005 0x00000001

以上可见,栈$esp 将参数对象指针、参数x、参数y,按照从右往左的顺序依次压入了栈。

综上所述,C++程序中函数调用时的参数传递方法与C语言函数的不同点是,除了参数之外,对象指针也会被传递。

最近发表
标签列表