簡體   English   中英

C函數指針-刪除參數時會發生什么?

[英]C Function Pointers - What happens when you drop an argument?

所有。 我目前正在使用一個舊的已建立代碼庫的新項目,而該項目基本上沒有文檔記錄(即每個文件平均1條單行注釋)。 我遇到了我以前從未見過的東西,並且不確定如何解釋。

首先,它們在頭文件(.h)中以以下形式定義函數類型和函數:


typedef void (*SOME_FUNCTION)(void *data, EXECUTION_CONTEXT *ec);
void add_function(SOME_FUNCTION aFunction, void *data);

在主源文件(.c)中,定義了一個函數:


void add_function(void (*f)(void *data), void *data) 
{
   (Some code here)
}

好的,有一個函數指針...但是第二個參數ec到底發生了什么? 為什么有人會使用這樣的代碼設計? 作為參考,當使用函數add_function時,它以以下形式使用:


void passedFunction(void *data, EXECUTION_CONTEXT *ec) 
{
    (Stuff the function does.)
}

void CallingFunction()
{
    data = (some data stuff);
    add_function((SOME_FUNCTION)passedFunction, data);
}

因此,如您所見,傳遞的函數使用適合原始SOME_FUNCTION參數簽名的正確形式,但是add_function參數的定義只有一個參數短。

形式上,結果是不確定的:如果類型匹配,則只能通過函數指針調用函數。

至於實際發生的情況,這取決於調用約定以及函數對參數的作用。 很有可能結果並不理想。

要補充詹姆斯的答案:

由於默認的調用約定很可能是cdecl ,所以調用站點負責在passedFunction返回之后清理堆棧。 由於調用站點知道它僅向被調用方傳遞了1個參數,因此編譯器可以正常清理堆棧(即使從技術上講這是未定義的行為)。

但是,將passedFunction上的調用約定更改為stdcall ,您將參加一些煙花大會。

在下面的示例代碼中,在檢查過程中似乎沒有函數指針中定義的變量重要。 下面的代碼無需警告即可編譯。

#include <stdio.h>

int temp(int (*m)());

int main(int argc, char *argv[]) {
        return temp(main);
}

int temp(int (*m)()) {
        return 1;
}

但是,下面的代碼將引發錯誤。

#include <stdio.h>

int temp(void (*m)());

int main(int argc, char *argv[]) {
        return temp(main);
}

int temp(void (*m)()) {
        return 1;
}

由於這個; 似乎編譯器(至少在我的情況下為GCC)僅關心函數指針的返回值。 有趣的是,您可以正確發送參數,但是如果未指定參數(在我們的示例m()中),則調用m()中的變量將是垃圾。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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