[英]Limit for nested function calls in C (C99)
根據C99,函數的嵌套調用是否有限制?
例:
result = fn1( fn2( fn3( ... fnN(parN1, parN2) ... ), par2), par1);
注意:此代碼絕對不好,因為它很難管理; 但是,此代碼是從模型自動生成的,因此不存在可管理性問題。
沒有直接的限制,但是僅要求編譯器允許各種類別的一些最低限制:
根據C11標准 :
5.2.4.1轉換限制1實現應能夠轉換和執行至少一個程序,該程序包含下列每個限制的至少一個實例: 18)
...
- 完整表達式中帶括號的表達式的63個嵌套級別
...
- 邏輯源代碼行中的4095個字符
18)實施過程中應盡可能避免施加固定的翻譯限制
不,沒有限制。
例如,這是一個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)
。
不會。由於這些功能是一個接一個地執行的,因此沒有問題。
int res;
res = fnN(parN1, parN2);
....
res = fn2(res, par2);
res = fn1(res, par1);
執行是線性的,先前的結果將用於下一個函數調用。
編輯:如注釋中所述,解析器和/或編譯器可能無法處理此類丑陋的代碼。
如果這不是一個純粹的理論問題,答案可能是“嘗試重寫您的代碼,因此您無需這樣做,因為對於大多數理智的用例而言,限制已綽綽有余”。 如果這純粹是理論上的,或者您確實確實需要擔心此限制並且不能僅僅重寫,請繼續閱讀。
C11標准的第5.2.4節( 最新草案,可免費獲得,幾乎相同 )規定了支持哪些實現所需的各種限制。 如果我沒看錯的話,您最多可以嵌套63個級別。
但是, 允許實現支持更多, 實際上,它們可能支持。 我很難找到適用於GCC的文檔(我發現的最接近的是預處理器中的表達式),但是我希望它在編譯時除了系統資源外沒有硬限制。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.