C++ 是否在c中为内联复制了两次参数?
关于c/c++中的内联函数和参数复制,我有一个问题。假设我希望在不使用内联说明符的情况下运行此函数:C++ 是否在c中为内联复制了两次参数?,c++,c,function,inline,C++,C,Function,Inline,关于c/c++中的内联函数和参数复制,我有一个问题。假设我希望在不使用内联说明符的情况下运行此函数: void my_func(int param) { my_inner_func(param); } 参数将首先复制到我的函数,然后再复制到我的内部函数。如果函数my_func是inline,编译器是否只为my_inner_func参数复制param一次或两次。 我将非常感谢您的帮助 编辑:我想对C++和C++的解释有所不同。 < P> C和C++都指定了程序在抽象机器上的行为。< /P
void my_func(int param)
{
my_inner_func(param);
}
参数将首先复制到我的函数
,然后再复制到我的内部函数
。如果函数my_func
是inline
,编译器是否只为my_inner_func
参数复制param
一次或两次。
我将非常感谢您的帮助
编辑:我想对C++和C++的解释有所不同。 < P> C和C++都指定了程序在抽象机器上的行为。< /P>
myu-func
的int-param
存在于这个抽象机器中,它不同于myu-inner-func
的int-param
。他们有不同的身份。如果你取其中一个的地址和另一个的地址,它们肯定是不相等的
但是,如果你没有任何一个人的地址,他们都不需要有地址
如果您对一个int
所做的只是赋值或初始化它,然后使用它来赋值或初始化另一个int
,并且编译器可以证明没有定义的方法通过间接(如指针)到达中间int
,那么中间int
不需要存在于实际的目标机器上
某些编译器在链接时执行此操作时遇到问题。其他人则不然
某些操作将阻止该int
的存在。其他人不会
在您的示例中,我看不到任何东西需要中间
int
存在于目标计算机上。inline
它只是对编译器的一个“建议”,可以或不能inline
您的函数。显然,您也可以选择inline
一个未明确声明inline
的函数
换句话说,根据您的编译器和优化设置,您应该查看生成的汇编程序以获得答案。编译器可以做它想做的事情,只要它遵循
规则就行
该规则规定,在您尝试和测量程序状态的任何时候,它都会给出正确的答案
如果不进行测量,它可以重新排序操作
当编译器进行优化时,它将能够删除内联和非内联代码的参数的第二个副本,除非有代码试图发现这一点。然后,它必须生成符合“仿佛”规则的代码,并可能增加副本数。这取决于具体情况。内联函数(顺便说一句,最好让编译器决定是否执行此操作)必须公开与正常版本(而非内联版本)相同的可观察行为。因此,最简单的方法是复制参数两次。如果内部函数没有写入,编译器可以足够聪明地优化第二个副本。如果函数没有内联,在大多数架构上,函数调用本身的成本将明显高于复制int
在参数在寄存器中传递的系统上,用于传递单个int
参数的寄存器在输入第一个函数时将已经保存该值,并且它可以将其传递到下一个函数,而无需创建新的副本
不要为小事操心 嗯,在内联函数中,编译器可以访问内联所涉及的所有代码,因此它可以检测您是否在实际修改参数,因此如果您的函数不修改参数,它可以避免复制。说到这里,你面临的问题是什么?我编辑了这个问题inline
关键字和函数内联很久以前就变得不相关了。更多信息请参见。@Quentin他们关系密切。因为外部函数不再调用内部函数后的值,所以即使内部函数对它进行写入,编译器也会使用相同的对象,这是安全的。当然,你所描述的是另一个可以优化的极端情况。好吧,如果你不能假设OP在调用后没有读取param
,我认为你不能假设OP在任何时候都没有获取任何一个param的地址,这是进行优化的另一个要求。看起来我记得决定性的“inline
被忽略了”有什么惊人的错误。。。我的错。公平地说,这是一个相当模糊的主题,因为它涉及到标准措辞和实现细节。我认为“建议”并不能很好地描述inline
所做的事情。它允许在多个翻译单元中定义,从而放松了ODR,并且实际上增加了对使用该函数的所有翻译单元中定义的新要求。这一新要求的预期副作用是允许跨翻译单元进行内联扩展。另一方面,如果使用LTO,这不是严格的要求。这是一个内联建议,就像授予驾驶执照是一个驾驶汽车的建议一样(糟糕的类比,并不是所有级别都适用)。@user2079303..和我最差的英语一样糟糕…;)“没问题,只是好奇。”不来梅,如果是这样的话,恐怕这不是一个正确的提问论坛。