簡體   English   中英

為什么`(*)`可以從函數參數列表中的函數指針中省略?

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

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