我对c / c ++和参数复制中的内联函数有疑问。让我们假设我想在没有内联说明符的情况下运行此函数:
void my_func(int param)
{
my_inner_func(param);
}
param将首先复制到my_func
,然后再复制到my_inner_func
。如果函数my_func
为inline
,那么编译器只会为param
参数复制my_inner_func
一次,或者反复复制两次ng-style
。
我将非常感谢你的帮助。
编辑:如果它有所不同,我想请求解释c和c ++。
答案 0 :(得分:7)
C和C ++都以抽象机器的形式指定程序的行为。
my_func
的{{1}}存在于此抽象机器中,它与int param
的{{1}}不同。他们有不同的身份。如果你取一个地址和另一个地址,它们保证比较不相等。
但是如果你不接受任何一个的地址,就不需要有地址。
如果您对my_inner_func
所做的只是分配或初始化它,那么使用它来分配或初始化另一个int param
,编译器可以证明没有定义的方法来到达int
int
通过间接(如指针),中间int
不需要存在于实际的目标机器上。
某些编译器在链接时遇到此问题。其他人没有。
某些操作会阻止int
存在被忽略。其他人不会。
我的示例中没有看到任何要求目标计算机上存在中间int
的内容。
答案 1 :(得分:4)
只要符合as if
规则,编译器就可以完成它想要的工作。
规则规定,在尝试测量程序状态的任何时候,它都会给出正确的答案。
如果您没有测量它,它可以重新排序操作。
当编译器进行优化时,它将能够删除内联和非内联代码的第二个参数副本,除非有代码试图发现这一点。然后,它必须生成满足as-if规则的代码,并可能增加副本数量。
答案 2 :(得分:2)
inline
这只是一个"建议"编译器,可以或不能inline
你的功能。显然也可以选择inline
一个你没有明确声明inline
的函数。
换句话说,根据您的编译器和优化设置,您应该查看生成的汇编程序以获得答案。
答案 3 :(得分:2)
这取决于。内联函数(顺便说一句,让编译器决定是否执行此操作最好)必须公开与普通版本相同的可观察行为,而不是内联版本。所以最简单的方法是复制参数两次。编译器可能足够聪明,可以优化第二个副本,如果内部函数没有写入它。
答案 4 :(得分:0)
如果没有内联函数,在大多数体系结构中,函数调用本身的成本将显着高于复制int
。
在参数在寄存器中传递的系统上,传递单个int
参数的寄存器在输入第一个函数时已经保存了该值,并且可以将其传递给下一个函数而不创建新副本。
不要为小东西出汗!
答案 5 :(得分:0)
好吧,在内联函数中,编译器可以访问所有涉及到内联的代码,因此它可以检测您是否实际修改了参数,因此如果您的函数没有,它可以避免复制修改参数。说这个,你面临的问题是什么?