簡體   English   中英

我可以以某種方式在ANSI C中使用嵌套函數嗎?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM