C(C99)中嵌套函数调用的限制

时间:2018-02-08 08:08:34

标签: c c99

根据C99嵌套调用函数是否有限制?

示例:

result = fn1( fn2( fn3( ... fnN(parN1, parN2) ... ), par2), par1);

注意:这段代码绝对不是一个好习惯,因为很难管理;但是,此代码是从模型自动生成的,因此可管理性问题不适用。

4 个答案:

答案 0 :(得分:7)

没有直接的限制,但只需要编译器允许对各种类别进行一些最小限制:

来自C11 standard

  

5.2.4.1翻译限制   1实现应能够翻译和执行至少一个包含以下每个限制的至少一个实例的程序: 18)

     

...

     
      
  • 完整表达式中括号内表达式的嵌套级别
  •   
     

...

     
      
  • 逻辑源行中的4095个字符
  •   
     

18)实施应尽可能避免强加固定的翻译限制

答案 1 :(得分:4)

没有。没有限制。

例如,这是一个C片段:

int func1(int a){return a;}
int func2(int a){return a;}
int func3(int a){return a;}

void main()
{
func1(func2(func3(16)));
}

相应的汇编代码为:

0000000000000024 <main>:
  24:   55                      push   %rbp
  25:   48 89 e5                mov    %rsp,%rbp
  28:   bf 10 00 00 00          mov    $0x10,%edi
  2d:   e8 00 00 00 00          callq  32 <main+0xe>
  32:   89 c7                   mov    %eax,%edi
  34:   e8 00 00 00 00          callq  39 <main+0x15>
  39:   89 c7                   mov    %eax,%edi
  3b:   e8 00 00 00 00          callq  40 <main+0x1c>
  40:   90                      nop
  41:   5d                      pop    %rbp
  42:   c3                      retq   

%edi寄存器存储每个函数的结果,%eax寄存器存储参数。如您所见,有三个callq指令对应于三个函数调用。换句话说,这些嵌套函数被逐个调用。没有必要担心堆栈。

正如评论中所提到的,当代码嵌套太深时,编译器可能会崩溃。 我编写了一个简单的Python脚本来测试它。

nest = 64000

funcs=""
call=""

for i in range(1, nest+1):
    funcs += "int func%d(int a){return a;}\n" %i
    call += "func%d(" %i

call += str(1) # parameter
call += ")" * nest + ";" # right parenthesis

content = '''
%s
void main()
{
%s
}
''' %(funcs, call)

with open("test.c", "w") as fd:
    fd.write(content)

nest = 64000没问题,但640000会导致gcc-5.real: internal compiler error: Segmentation fault (program cc1)

答案 2 :(得分:1)

没有。由于这些功能是逐个执行的,所以没有问题。

int res;
res = fnN(parN1, parN2);
....
res = fn2(res, par2);
res = fn1(res, par1);

执行是线性的,之前的结果用于下一个函数调用。

编辑:正如评论中所解释的,解析器和/或编译器可能存在处理这些丑陋代码的问题。

答案 3 :(得分:1)

如果这不是一个纯粹的理论问题,那么答案很可能是&#34;尝试重写代码,这样你就不需要这样做,因为对于大多数理智的用例来说,这个限制已经足够了# 34 ;.如果这纯粹是理论上的,或者您确实需要担心这个限制并且不能重写,请继续阅读。

C11标准的第5.2.4节(latest draft, which is freely available and almost identical)规定了要求支持的实现的各种限制。如果我正确阅读,你可以达到63级嵌套。

但是,实现允许支持更多,实际他们可能会支持。我很难找到GCC的相应文档(我发现最接近的是预处理器中的表达式),但我认为除了编译时的系统资源外,它没有硬限制。