如何获得C ++函数的大小?

时间:2011-01-02 17:35:29

标签: c++ function

如何在C ++中获取函数的大小?

假设我有一个功能:

void f()
{
/*do something*/
}

...“f的大小”是指代码/*do something*/的大小,从指向f的地址开始。

7 个答案:

答案 0 :(得分:12)

你做不到。它甚至可能不是一个定义明确的概念。例如,请考虑以下代码:

int f(int a) {
    return (3*a)+1;
}

int g(int a) {
    return (2*a)+1;
}

我怀疑这个特定的例子在实践中发生了,因为它不是一个优化,但允许编译器引入一个计算a+1然后返回的代码块,然后跳转到该块fg的每个入口点(在每种情况下进行乘法后)。那么f的大小是多少?它应该包括共享块的大小吗?那么大一半?声称函数f具有大小。

在C ++术语中没有意义

此外,“指向f的指针”可能不仅仅是函数f的地址。它确实提供了一种到达f入口点的方法,但是例如在交互模式下的ARM处理器上,指向由Thumb代码组成的函数的指针实际上是第一条指令的地址加1。实际上,当执行跳转到函数时,CPU会屏蔽指针的lsb,但该位会告诉CPU切换到Thumb模式而不是ARM模式。所以指针的值不是函数的地址(尽管它很接近)。无论如何,函数的入口点不一定是它的开头 - 如果你的编译器创建常量池或类似的,它们可以在可执行代码之前。

可能有特定于平台的方法来检查您的可执行文件(文件,或加载到内存后,或两者),并说明什么代码与C ++的功能相关联。毕竟,这是调试信息的用途。但是在标准C ++中没有办法做到这一点,标准不要求任何这样的机制存在。

答案 1 :(得分:4)

嗯,从技术上来说,我不相信你可以,而不是便携。

但实际上你可以做到这一点:

void f() { ... }
void g() { ... }

char *fp = (char *)&f;
char *gp = (char *)&g;

int size = gp - fp;

你有点依赖编译器在对象文件中的'f'之后添加'g',并且链接器也是如此,在f之后放置g。

然后你只是减去指针以获得差异。

也可能涉及填充和其他可能的问题,因此它可能不是“完全”函数的大小。

答案 2 :(得分:3)

大多数编译器都有输出程序集的选项。这样做,查看处理器文档中的说明并进行数学计算。

答案 3 :(得分:1)

使用文本编辑器和wc? :)你还不清楚你的意思是函数的大小,但我假设你的意思是函数的机器代码的大小。没有办法做到这一点,特别是在编译器之间可移植。许多编译器只是简单地将程序转换为汇编程序,因此他们不知道机器代码的大小。

充其量,你可以在它之后放一个函数并减去地址,希望它们会占用内存的连续和连续部分,但实际上并不能保证编译器会这样做。

答案 4 :(得分:1)

我建议你做一些类似strlen的事情,除非你使用return opcode而不是零作为终结符。

答案 5 :(得分:0)

我想以字节为单位获取生成代码的大小,这样我就可以将代码复制到新的位置并从那里执行。我知道这是可行的,因为我使用了2函数和减法方法 void f(){...}  void g(){...}
char * fp =(char *)& f; char * gp =(char *)& g;
int size = gp - fp; 它在发布模式下在visual studio中工作。 我提出这个问题的原因是因为我对编译器优化仍有一些问题,而且我需要一个更安全的方法。

答案 6 :(得分:-1)

功能没有“大小”。就C ++而言,它们不是对象,也不占用任何存储空间。实际上,它们在生成的可执行二进制文件中作为执行指令存在。