【问题标题】:emulating `alloca()` in C在 C 中模拟 `alloca()`
【发布时间】: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_ptruniq_ptr 这样的智能指针会自动做到这一点。

标签: c alloca


【解决方案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 需要在典型实现上操作堆栈指针。您不能只从链接器调用函数,所涉及的编译器必须提供一些支持(至少它不能重新排序堆栈上对象的分配等)。与自动变量相比,分配对象的生命周期也存在差异。
    猜你喜欢
    • 2014-07-20
    • 2012-02-27
    • 2015-06-08
    • 1970-01-01
    • 2013-06-19
    • 2021-03-07
    • 2013-10-03
    • 2015-09-07
    • 1970-01-01
    相关资源
    最近更新 更多