我知道编译器可能不会将inline
函数展开到调用函数中,以避免与调用外部函数相关的开销.然而,我也知道,inline
函数的链接方式与外联函数不同,所以我不能指望它们的行为完全相同.
虽然我实际上在使用C++,但我正在使用api开发一个程序,在这个程序中使用C宏很方便,它们看起来像:
#define func_alloca(ptr) do { *ptr = alloca(size); memset(*ptr, 0, size); }
Run Code Online (Sandbox Code Playgroud)
为了不在不同的函数中多次重复代码,对我来说能够实现一系列这些alloca
调用是有用的.我的问题是,(特别是在gcc中,因为alloca
是实现定义的),我可以alloca
在inline
函数内部使用函数初始化堆栈中的变量,并指望它们在外部工作吗?这是我想要做的一个例子:
inline void uses_alloca(type*& ptr){
// do stuff
func_alloca(ptr);
}
void calls_inline(){
type *local_ptr;
uses_alloca(local_ptr);
// is local_ptr valid?
}
Run Code Online (Sandbox Code Playgroud)
如果确实有效,它会一直有效吗?不仅如此,编译器选择将inline
函数展开到调用函数中?
编辑:
我的猜测是,这可能会起作用,因为alloca
调用do{}
在宏中包含的局部作用域之外已经有效,并且因为,如果我理解正确,函数实际上在C++中实际上没有与do{}
块.我的问题依然存在:这alloca
是应该在gcc中运行的吗?这是定义的行为吗?
声明函数inline
不会将包含的变量的范围扩展到扩展它的范围.因此,无论alloca
分配什么都不能保证在调用函数 的上下文中有效uses_alloca
.如果你使用宏 func_alloca
,你很好,因为宏文本在字面上扩展到位.但是,使用alloca
它本身通常被认为是一种不好的做法.
如果您使用 GCC,预期行为是其中的函数alloca
不会自动内联。来自tree-inline
:
/* Refuse to inline alloca call unless user explicitly forced so as
this may change program's memory overhead drastically when the
function using alloca is called in loop. In GCC present in
SPEC2000 inlining into schedule_block cause it to require 2GB of
RAM instead of 256MB. Don't do so for alloca calls emitted for
VLA objects as those can't cause unbounded growth (they're always
wrapped inside stack_save/stack_restore regions. */
Run Code Online (Sandbox Code Playgroud)
这当然没有考虑:
内联的GCC 手册页警告说内联函数不适合alloca
以及为什么使用 alloca() 不被认为是好的做法?还有一些恐怖故事。
基本上,如果您担心内联可能会影响代码的语义,请不要依赖它。
归档时间: |
|
查看次数: |
841 次 |
最近记录: |