使用 gcc (resp. MinGW) 编译器的 C 中函数的参数数量是不是有上限?

Posted

技术标签:

【中文标题】使用 gcc (resp. MinGW) 编译器的 C 中函数的参数数量是不是有上限?【英文标题】:Is there a maximum number of parameters for functions in C with the gcc (resp. MinGW) compiler?使用 gcc (resp. MinGW) 编译器的 C 中函数的参数数量是否有上限? 【发布时间】:2014-09-30 13:24:32 【问题描述】:

我知道在遵循良好做法时我永远不会达到这样的限制。但是,我需要使用带有 lots 参数的自动生成的函数(而且我无法用它更改任何内容,我从其他人那里收到了该函数)。

所以:我可以在 gcc 中使用的最大参数数量是多少? MinGW?

我发现this 关于 C++ 语言规范。和this 关于 C 语言标准限制。我感兴趣的是“现实世界”限制/实施细节是什么的问题。尤其是在 gcc 和 MinGW 中。

另外:当达到这样的限制时,我会收到什么样的错误消息?当通过 extern "C" 声明在 C++ 应用程序中使用 C 代码时,这对“正常”C 限制有什么不同吗?除了参数数量之外,可能还有其他限制适用于此,例如像最大线长这样的东西?或者最大堆栈大小?

谢谢!

【问题讨论】:

据我所知(你的第一个链接说)限制是 c++ 中的 256 个参数和 c 中的 127 个参数。行长没有问题,因为您可以将一行分成更多行。只有当你有巨大的结构作为参数(而不是指向结构的指针)时,堆栈大小才会成为问题。 这就是标准规定的“最小”数字(我在我的问题中链接了相应的帖子)。我想知道的是“真实”数字,即特定编译器的限制。行长:我不确定,但我认为,预处理器确实删除了任何换行符等(我们需要在每行末尾添加“;”的原因) - 所以将它们分成多行(我已经当然完成)并没有什么不同,我想。堆栈大小:好的,我只需要传递指针,所以这似乎不是限制。 它可能是 ABI、处理器和编译器特定的。我猜你有一个x86-64。然后在实践中限制与堆栈框架和堆栈大小有关,所以我猜你可能会传递几千个参数。我建议你做一个简单的测试:为某个参数 N 编写一个脚本,在一个文件中生成一个包含 N 个参数的函数(例如,计算所有参数的总和),并在另一个文件中使用 main 调用该函数. 为什么你希望你的代码处理超过指定最低语言的语言?当然,您的代码将需要强制执行 some 限制,以便它可以标记不守规矩的输入。如果它使用规范最小值(127),损失是多少? @chux:目前大约有 500 个参数并且工作正常(尽管我有另一个错误,但我花了几个小时都找不到,因此开始考虑其他原因 - 例如最大参数数量)。他们不太可能得到更多,但是当我开始考虑这个限制时,这个话题引起了我的兴趣,我问了这个问题。这是一个由 Matlab 生成的包装函数,必须与 S-Functions 做一些事情。但它的生成不是我的任务(我会让其他人意识到 c 标准中的这个限制,以防万一)...... 【参考方案1】:

C 标准 5.2.4.1 说:

4095 characters in a logical source line
127 parameters in one function definition
127 arguments in one function call

如果您有巨大的结构体作为参数,堆栈大小 (1MB - 8MB) 也是一个限制。

但所有这些限制都与所有好的做法相去甚远。

https://gcc.gnu.org/onlinedocs/gcc-4.3.5/cpp/Implementation-limits.html 表示 gcc 有更高的限制(仅受可用内存限制)。

【讨论】:

请注意,您提到的gcc 文档仅涵盖了 c 预处理器,而指示性并未真正涵盖这种情况。 有些微控制器的堆栈大小为 256 字节或更少。【参考方案2】:

在 C 中有多个参数的特殊库 (stdarg.h)。 使用这个库,您可以编写如下函数:

int a_function ( int x, ... )

    va_list a_list;
    va_start( a_list, x );

而且我认为没有特别的限制。


这是一个如何使用这个库的例子: (致:http://www.cprogramming.com/tutorial/c/lesson17.html)

#include <stdarg.h>
#include <stdio.h>

/* this function will take the number of values to average
   followed by all of the numbers to average */
double average ( int num, ... )

    va_list arguments;                     
    double sum = 0;

    /* Initializing arguments to store all values after num */
    va_start ( arguments, num );           
    /* Sum all the inputs; we still rely on the function caller to tell us how
     * many there are */
    for ( int x = 0; x < num; x++ )        
    
        sum += va_arg ( arguments, double ); 
    
    va_end ( arguments );                  // Cleans up the list

    return sum / num;                      


int main()

    /* this computes the average of 13.2, 22.3 and 4.5 (3 indicates the number of values to average) */
    printf( "%f\n", average ( 3, 12.2, 22.3, 4.5 ) );
    /* here it computes the average of the 5 values 3.3, 2.2, 1.1, 5.5 and 3.3
    printf( "%f\n", average ( 5, 3.3, 2.2, 1.1, 5.5, 3.3 ) );

【讨论】:

这似乎仍然会遇到传递给@mch 的答案中提到的单个函数调用的 127 个参数的限制。【参考方案3】:

标准不知道,但是越过堆栈,可以传递任意数量的参数,如果通过寄存器,数量受寄存器数量限制。在 c 语言中,您可以通过堆栈的值传递结构。

【讨论】:

c 标准 5.2.4.1 说:127 parameters in one function definition127 arguments in one function call

以上是关于使用 gcc (resp. MinGW) 编译器的 C 中函数的参数数量是不是有上限?的主要内容,如果未能解决你的问题,请参考以下文章

mingw和gcc的关系?mingw具有gcc的全部核心编译功能吗

使用 Pip 安装 Python 包时如何使用 MinGW 的 gcc 编译器?

mingw64 的 gcc 不使用 mingw 套件的汇编程序

mingw-w64和Linux下的GCC有区别吗

如何将使用sysioctl.h的代码移植到MinGW gcc中?

使用 MinGW32 GCC 编译。只告诉链接库一次?