2013-03-27 100 views
4

以下問題Function pointer in Visual Studio 2012我已經開始想知道某些任務的合法性C.函數指針賦值

到函數指針

下面的代碼以警告編譯,就像我所期望的,因爲分配的功能要求參數比函數指針聲明描述(GCC 4.8):如果改變代碼,使得分配的功能需要更少PARAM出現

#include <stdio.h> 

int test(int x, int y) 
{ 
    printf("%d", x); 
    printf("%d", y); 
    return 0; 
} 

int main() 
{ 
    int (*test_ptr)(int); 
    test_ptr = test; 
    test_ptr(1); 
    return 0; 
} 

相同的警告eters(GCC 4.8)。再次,這是預期的。

然而,下面的代碼編譯沒有一個單一的警告,儘管分配的功能需要2個參數,而不是0(GCC 4.8):

#include <stdio.h> 

int test(int x, int y) 
{ 
    printf("%d", x); 
    printf("%d", y); 
    return 0; 
} 

int main() 
{ 
    int (*test_ptr)(); 
    test_ptr = test; 
    test_ptr(); 
    return 0; 
} 

否鑄件的任何地方參與。

任何人都可以解釋這種編譯器的行爲嗎?

回答

9

以下:

int (*test_ptr)(); 

需要一個未指定數目的參數,而不是零級的參數。

對於後者,寫

int (*test_ptr)(void); 

P.S.使用零參數調用雙參數函數會導致未定義的行爲。

+0

即使使用C99? – SomeWittyUsername 2013-03-27 08:10:13

+0

@icepack C99不棄用具有未指定數量參數的函數。 – 2013-03-27 08:11:34

+0

謝謝大家,傻我 – SomeWittyUsername 2013-03-27 08:12:36

2

從函數指針轉換爲函數指針是合法的。非法的是調用一個函數指針,其類型與實際指向的函數不兼容。

C99 6.3.2.3 par。 8:

指向一種類型函數的指針可能會轉換爲指向另一種類型函數的指針,然後再返回;結果應該比較 等於原始指針。如果轉換後的指針可以用來調用其 類型不是與指向的類型兼容的功能, 行爲是不確定的

如果編譯器警告正是爲未定義的行爲,應在test_ptr();警告。但編譯器不能期望針對所有未定義的行爲發出警告,或僅針對未定義的行爲發出警告。


這種靜態分析(別人和我的工作)會盡力提醒所有不確定的行爲,只爲未定義行爲。很多妥協的參與,但在這種特殊情況下:

$ cat > fp.c 

int test(int x, int y) 
{ 
    printf("%d", x); 
    printf("%d", y); 
    return 0; 
} 

int main() 
{ 
    int (*test_ptr)(); 
    test_ptr = test; 
    test_ptr(); 
    return 0; 
} 
$ frama-c -val fp.c 
... 
fp.c:13:[value] warning: Function type must match type at call site: assert(function type matches) 

線13 test_ptr();

+0

如果它是合法的,爲什麼GCC會在前2個代碼段中發出警告? – SomeWittyUsername 2013-03-27 08:14:57

+0

@icepack,因爲編譯器設計者認爲你可能想知道你正在做一些不尋常的事情。除了不警告每一個未定義的行爲外,它還可以警告那些不是未定義行爲的事情(或者在這種情況下,可能會導致未定義行爲的事情,以致於它知道它以後將無法警告如果你使用指針錯誤)。 – 2013-03-27 08:18:38

+0

@icepack其實我很驚訝你所鏈接到的問題中描述的行爲(http://stackoverflow.com/questions/15653604/function-pointer-in-visual-studio-2012/15653714),但Visual Studio是已知的不要提供C99編譯器,即使我挖掘C90並指出它也允許這樣做,那不會導致它被修復。您鏈接的問題中的代碼段肯定是符合C99的。 – 2013-03-27 08:26:41