[英]Can I somehow use nested functions in ANSI C?
我有高級語言的背景,例如Java / Kotlin / Scala。 現在我需要創建一個C庫,但是我很難在沒有閉包的情況下工作。
在GCC中有一個很好的擴展,稱為“嵌套函數”,(如果我正確理解的話)正是我需要的。 Apple“阻止”擴展看起來也很有趣。 但我需要一個可以與任何編譯器一起使用的代碼。
現有解決方案是否存在? 我見過一些允許生成C代碼的項目: https : //github.com/dbohdan/compilers-targeting-c 。 但我真的不需要另一種語言,只需要一個功能 - 閉包。 (我認為很難保持完全不同的語言,結果C代碼將不會被優化)。
UPD一些解釋,為什么我需要閉包。
假設我們有一些函數, connect(void (*on_failed_callback)());
。 它以某種方式管理連接,當連接丟失時,它會調用回調。 它需要0個參數,但我想創建一些函數,它將帶來一些帶回調的數據。 如果我已經正確理解,最常用的解決方案是使用一些arg connect(void (*on_failed_callback)(void *callback_arg), void* arg);
傳遞回調connect(void (*on_failed_callback)(void *callback_arg), void* arg);
。 但它導致了樣板代碼,可以通過嵌套函數修復。
所以下一個代碼:
void connect(void (*on_failed_callback)(void* arg), void* arg) {
...
on_failed_callback(arg);
}
void print_error(char* error) {
printf(error);
}
void main() {
char *msg = "Failed connection";
...
connect(print_error, msg);
}
可以簡化為下一個:
void connect(void (*on_failed_callback)()) {
...
on_failed_callback();
}
void print_error(char* error) {
printf(error);
}
void main() {
char* msg = "Failed connection";
...
void callback() {
print_error(msg);
}
connect(callback);
}
我的意思是,我想要一些工具/應用程序,用閉包/嵌套函數分析我的代碼並生成純ANSI C代碼。
對於特定的示例,您已經詢問過使用C的方法實現類似於閉包的方法,因為它將函數指針打包,並且需要與函數一起使用的數據。
typedef struct {
char sBuff[128]; // data for the function to use
void (* func) (char* error); // pointer to function to execute
} ErrorMsg;
void connect(ErrorMsg myMsg) {
...
myMsg.func(myMsg.sBuff); // call the function with the packaged data
}
// the function that we will be encapsulating with the data to be
// used.
void print_error(char* error) {
printf(error);
}
void main() {
ErrorMsg msg = {"Failed connection", print_error} ;
…
connect(msg); // invoke our function package and its data.
}
如果在使用函數包時,您希望添加其他數據,您可以按照以下方式執行此操作。
typedef struct {
char sBuff[128]; // packaged data for the function to use
void (* func) (char* error, int iExtra); // pointer to function to execute
} ErrorMsg;
void connect(ErrorMsg myMsg) {
...
myMsg.func(myMsg.sBuff, errno); // call the function with the packaged data and extra info
}
// the function that we will be encapsulating with the data to be
// used.
void print_error(char* error, int iExtra) {
printf(error, iExtra);
}
void main() {
ErrorMsg msg = {"Failed connection: errno %d", print_error} ;
…
connect(msg); // invoke our function package and its data.
}
現有解決方案是否存在?
這取決於你的意思。 標准C不提供閉包,嵌套函數或lambda /塊作為語言功能。 但是在其他語言中沒有任何東西可以用C語言中沒有的任何或所有這些語言做。 事實上,某些語言中確實有這些功能本身用C實現
特別是,您的第一個示例大致是通用回調的正常C語言。 回調函數接受指向包含所需數據的對象的指針,並且回調注冊接口接受指向適當對象的指針以及指向該函數的指針。 觸發回調時,會將已注冊的數據指針傳遞給它。
順便提一下,請注意,這是一個比單獨使用閉包更通用的工具,因為回調將在其上運行的數據不需要在定義函數的范圍內。 除此之外,這允許提供標准的,可重用的回調實現,其中與特定數據的關聯僅在回調注冊時進行。 如果多個回調可以同時與同一事件相關聯,則它還允許對同一事件重用相同的回調,並使用不同的數據。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.