代码之家  ›  专栏  ›  技术社区  ›  Taylor

调用约定是否阻止可变大小的返回值?

  •  1
  • Taylor  · 技术社区  · 6 年前

    如前所述 here ,当从C函数返回可变大小数据时,您可以:

    1. 传递指针和最大长度。返回一个标志,指示是否已达到最大值。
    2. 返回指向动态分配数据的指针。
    3. 返回指向全局数据的指针。

    在典型的硬件上,有没有什么调用约定会阻止通过调用堆栈返回动态大小的数据?

    一些C编译器有VLA(或 alloca )所以调用堆栈上的可变大小数据是可能的。通过增加调用者的堆栈帧来实现可变大小的数组返回值似乎相当简单,就好像声明了VLA而不是函数调用一样。返回后,被调用方将保留元素计数,后跟元素。

    2 回复  |  直到 6 年前
        1
  •  1
  •   rici    6 年前

    在弗拉斯之前,我们用 alloca 标准库函数,它实际上返回可变大小的数据。(数据是未初始化的,但这对实现不是必需的)所以很明显这是可能的。

    然而,有一个重要的细节: 阿洛卡 每次调用时都分配存储,并且没有 freea . 释放存储器的唯一方法是从调用alloca的函数返回。

    对于本地存储分配来说,这是一个看似合理的接口,但对于返回有用数据的函数来说却不是那么好。如果你打电话 functionWithVariableReturnSize() 在一个循环中,最终返回的所有值都保存在堆栈帧中,直到框架退出。这可能是不可取的,而且这可能不是一个好主意,即使它匹配一些用例。

        2
  •  1
  •   John Bollinger    6 年前

    可变长度数组(这是一个可选特性)是C提供的唯一一种动态大小的数据结构,它具有不同于指针的源表示。C甚至不提供表示传递或返回数组的机制 完全 但是,因为数组值表达式会衰减为函数参数列表和 return 声明。然而,这不是一个调用约定的问题,而是语言设计中根深蒂固的方面。

    在那里 当然,调用影响函数返回值实现的约定注意事项,但是当涉及到返回结构类型的函数时,C实现必须处理那些最重要的实现。如果C支持返回数组,那么我认为在调用约定方面不需要太多新的东西来支持返回vla。