巢狀函數 是 GCC 擴展,非標準 C。它帶來閉包與詞法作用域特性,讓 C 具備函數式語言風格能力。
double foo(double a, double b) {
double square(double z) { return z * z; } // 巢狀函數
return square(a) + square(b);
}
void bar(int *array, int offset, int size) {
int access(int *array, int index) {
return array[index + offset]; // 捕獲 offset
}
for (int i = 0; i < size; ++i) {
// 使用 access(array, i)
}
}
void bar(int *array, int offset, int size) {
__label__ failure;
int access(int *array, int index) {
if (index > size) goto failure; // 跳轉至外層標籤
return array[index + offset];
}
for (int i = 0; i < size; ++i) { /* ... */ }
return 0;
failure:
return -1;
}
int (*get_square(void))(double) {
double square(double z) { return z * z; }
return square; // 回傳巢狀函數位址
}
// 呼叫端:int (*f)(double) = get_square(); f(3.0);
警告:外層函數返回後,其堆疊框架失效,呼叫此函數指標屬未定義行為(GCC 透過 trampoline 於堆疊生成代碼支援,但極度危險)。
-z execstack 或 mprotect)| 需求 | 標準 C 方案 | C++ 方案 |
|---|---|---|
| 狀態捕獲 | 結構體 + 函數指標 | Lambda 表達式 |
| 回呼 | void* context + 函數指標 | std::function + Lambda |
| 閉包 | 手動實現環境結構體 | Lambda 自動捕獲 |
巢狀函數展示編譯器擴展的強大與風險。生產代碼建議使用標準 C/C++ 替代方案,確保可移植性與安全性。