我知道以这种方式定义函数指针
struct handler_index {
const char *name;
int (*handler)();
};
允许对任何具有未指定(但非可变)数量和类型的参数的函数使用处理程序指针。
但我想知道与此相比,这个定义是否会影响代码或内存或执行时间的优化:
struct handler_index {
const char *name;
int (*handler)(int a, int b);
};
如果您想知道向函数指针添加更多参数如何具体影响函数指针- 它不会。无论参数数量如何,函数指针的大小都相同。
如果您想知道调用此类函数指针的效率:添加更多参数将导致生成代码以传递参数。所以是的,它会稍微影响调用的代码大小,并且可能会影响执行时间,具体取决于您的 CPU 在传递这些参数时可以拉出多少 ILP。
现代调用约定通常在寄存器中传递一些参数,因此您可能会或可能不会增加堆栈使用量。
要准确了解每次调用生成的代码之间的区别,请阅读调用约定(这里列出的太多了!)并检查从代码生成的 asm。但实际上,添加更多参数(在合理范围内)可能会产生非常小的影响,以至于它根本不重要。
正如 Cory 所说,它是函数指针还是只是一个常规的基本函数并不真正相关[除非在常规函数被内联的情况下,当然,函数指针通常不能——尽管如果情况足够具体,我已经看到编译器实际上弄清楚了“啊,我们总是在这里调用函数 X,所以让我们内联 X”——通常当函数指针是函数的参数时,而不是在结构中说)。
一般而言,将有所作为的是向函数调用添加参数。处理器必须将这些参数放在某个地方,即使它们进入寄存器,也可能需要额外的指令才能将值放入 RIGHT 寄存器。
但是,您的第一个示例非常糟糕,因为没有检查您的代码是否在做正确的事情。
此外,您需要一些非常病态的情况来使将参数传递给函数的开销大部分时间都在调用函数指针 - 希望您的函数不仅仅将一个数字添加到另一个数字。
话虽如此,传递很多论点,尤其是“难以获得”的论点可能真的很糟糕。我正在研究图形芯片模拟器,部分像素着色器处理单元中间有一个调试打印,很少打印,但它需要 7 或 8 个参数(除了调试级别 1000 或其他它是)。从各自的结构中找出这些参数并将它们粘贴到堆栈上需要相当长的时间,并放置一个“if (debuglevel >= 1000) ...”以便仅在实际需要时进行调用,制作代码该功能的速度提高了约 40%。