一些程式員認為在另一個函式內部定義一個函式稱為“嵌套函式”,但是現實是它不是嵌套函式,它被視為詞匯作用域,在C語言中,詞法作用域無效,因為編譯器無法達到/找到內部函式的正確記憶體位置,
C不支持嵌套函式,因為我們無法在C中的另一個函式內定義一個函式,我們可以在一個函式內宣告一個函式,但它不是嵌套函式,
由于嵌套函式定義無法訪問周圍塊的區域變數,因此它們只能訪問包含模塊的全域變數,這樣做是為了不必在目錄中查找全域變數,與C中一樣,有兩個嵌套作用域:本地和全域(除此之外,內置函式),因此,嵌套函式只有有限的用途,如果嘗試在C中使用嵌套函式,則將得到編譯時錯誤,
輸出:
編譯時錯誤:未定義對“視圖”的參考
GNU C編譯器的擴展允許宣告嵌套函式,在GCC擴展名下的嵌套函式的宣告需要以auto關鍵字為前綴/開頭,
另外,gcc主要通過Trampoline實作函式嵌套功能,那么什么是Trampoline呢?
Trampoline其實就是一段存在于堆疊上的可執行代碼,它由運行時動態生成,通過運行堆疊上的這段代碼跳轉到真正的目的代碼處,
至于函式嵌套為何要通過Trampoline去實作,這還得從嵌套函式的特點說起,因為它能夠訪問容器函式中的區域變數:
其中offset就是容器函式中的變數,可以在嵌套函式中直接參考,這看起來似乎不難實作:通過sp+offset即可輕松訪問容器函式的堆疊變數,但還有一種情況必須要考慮,那就是嵌套函式不僅僅可以在容器函式中直接呼叫,還可能通過函式指標在其他函式中間接呼叫,這時活動堆疊幀布局跟容器函式就不一樣了,通過sp+offset訪問到的不再是容器函式中的對應變數位置了,這樣就會得到意想不到的結果,
Trampoline可以有效的避免這種情況,因為Trampoline存在于容器函式的堆疊上,相對于要訪問的容器函式的變數相對位置是固定的,所以不管怎么呼叫嵌套函式,執行的都是堆疊上的Trampoline,這樣訪問到的容器函式的變數位置總是正確的,不過這要求在嵌套函式呼叫時容器函式不能退出,否則堆疊上的Trampoline可能會被覆寫,同樣會得到意想不到的結果,
而且如果嵌套函式中不參考容器函式中的任何變數,那么嵌套函式會被提升為普通函式,通過上面原理的分析,這點應該很好理解,
另外如果你想更好的提升你的編程能力,學好C語言C++編程!彎道超車,快人一步!
C語言C++編程學習交流圈子,QQ群1030652847【點擊進入】微信公眾號:C語言編程學習基地
分享(原始碼、專案實戰視頻、專案筆記,基礎入門教程)
歡迎轉行和學習編程的伙伴,利用更多的資料學習成長比自己琢磨更快哦!
編程學習書籍分享:

編程學習視頻分享:

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/229647.html
標籤:C
