[英]Why can `(*)` be omitted from a function pointer inside a function parameter list?
用gcc8編譯:
#include <stdio.h>
void some_func(void f1(void), void (*f2)(void))
{
printf("%d\n", f1);
printf("%d\n", f2);
}
給(僅)以下警告:
<source>:11:14: warning: format '%d' expects argument of type 'int', but argument 2 has type 'void (*)(void)' [-Wformat=]
printf("%d\n", f1);
<source>:12:14: warning: format '%d' expects argument of type 'int', but argument 2 has type 'void (*)(void)' [-Wformat=]
printf("%d\n", f2);
為什么f1
的類型與f2
相同? 只有f2
被聲明為函數指針。 我希望f1
根本不會編譯,因為它命名一個函數類型,而不是一個函數指針。 什么規則說,函數參數列表中的函數類型更改為指向該函數類型的指針?
因為標准( 6.7.6.3p8 )說明了這一點
參數聲明為''函數返回類型''應調整為''函數返回類型的指針'',如6.3.2.1所述 。
它類似於數組參數如何調整為指針(6.7.63.p7) ,如果你考慮它。
void some_func(void (void));
void some_func(void (*)(void));
是兼容的聲明,就像:
void other_func(char string[]);
void other_func(char *string);
是。
請注意,調整不會使void some_func(void (*)(void)
與void some_other_func(void (**)(void)
或void yet_another_func(void (*****)(void)
void some_func(void (*)(void)
兼容就函數而言,聲明不再真正反映使用,(盡管這是語言的原作者的意圖)。在標准化的C中,由於函數標識符如何衰減到指針以及由於無論你是否無關緊要使用函數類型或函數指針類型進行調用,可以任意調用任意函數*
:
#include <stdio.h>
int main()
{
(*puts)("hello world");
(******puts)("hello world");
(***&*&*puts)("hello world"); //& cancels a * as per 6.5.3.2p3
int (*p)(char const*) = puts;
int (**pp)(char const*) = &p;
int (***ppp)(char const*) = &pp;
(**ppp)("hello world"); //at least two asterisks required here
}
因為在C中,在這種情況下,函數名本身就是一個函數指針。 看到這個答案: 為什么使用函數名作為函數指針相當於將address-of運算符應用於函數名?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.