在 C 中模拟 `alloca()`
Posted
技术标签:
【中文标题】在 C 中模拟 `alloca()`【英文标题】:emulating `alloca()` in C 【发布时间】:2016-12-02 14:36:12 【问题描述】:如果您通读 GNU libs 文档,您会看到:
一些非 GNU 系统不支持 alloca,因此它的可移植性较差。 但是,用 C 编写的 alloca 的较慢仿真可用于 在有此缺陷的系统上使用。
假设 VLA 也不可用,alloca()
的 C 模拟会是什么样子?
【问题讨论】:
在 C++ 中这将相当容易,但我怀疑您是否可以在标准 C 中编写可移植的alloca
函数。
真的吗?你能给出一个提示,你将如何在 C++ 中做到这一点?
@user1095108 使用 C++ 你可以只使用 std::shared_ptr,我想。
@WillihamTotland 是的,如果你想从堆中分配。
一个 emulation 应该只尊重全局接口,我的意思是从当前函数返回时自动释放分配的块。本地对象的析构函数可以做到这一点,而像 shared_ptr
或 uniq_ptr
这样的智能指针会自动做到这一点。
【参考方案1】:
根据alloca()
是什么
alloca() 函数在栈中分配 size 个字节的空间 调用者的框架。这个临时空间会自动释放 当调用 alloca() 的函数返回给它的调用者时。
实现将是特定于平台的,并且可能编译器应该意识到这一点,因为生成的代码必须尊重堆栈帧处局部变量的非固定偏移量。因此,如果您的工具链没有 VLA - 您与它无关。
【讨论】:
【参考方案2】:由于您正在查看GNU libc documentation,您可能会考虑如何在 GCC 中进行模拟。
GCC 提供了cleanup
属性,允许在变量超出范围时调用清理函数。
void foo (void *p)
printf("foo: %p\n", p);
int main(void)
int x __attribute__((cleanup(foo)));
x = 7;
printf("%p\n", &x);
return 0;
在上面的程序中,当x
超出范围时,foo()
被传递给x
的地址。
【讨论】:
这很有趣但不是很有用,因为 gcc 提供了 alloca 作为内置函数。 @n.m.不总是。我的意思是,GCC 并不总是为alloca
生成内联代码。这就是 GNU libc 提供模拟实现的原因。
<alloca.h>
头文件显示:#ifdef __GNUC__ #define alloca __builtin_alloca
。它可能会也可能不会导致代码内联。 glibc 可以由 gcc 以外的编译器编译。
@n.m.如果不包含alloca.h
,如果标志导致GCC 不内联alloca()
,链接器将选择仿真。
alloca
需要在典型实现上操作堆栈指针。您不能只从链接器调用函数,所涉及的编译器必须提供一些支持(至少它不能重新排序堆栈上对象的分配等)。与自动变量相比,分配对象的生命周期也存在差异。以上是关于在 C 中模拟 `alloca()`的主要内容,如果未能解决你的问题,请参考以下文章