2017-08-04 89 views
0

在C/C++中,以下代碼完美無缺。爲什麼不能將具有返回值的函數分配給帶void的指針函數?

void *pa; 
void fa(void*); 

int a; // or any type 
pa = &a; 
fa(&a); 

我很困惑,爲什麼這不是函數的返回類型真:

void fa(void); 
    int fb(void); 
    void (*pa)(void); 
    int (*pb)(void); 

    pa = fa; pb = fb; // OK 
-> pa = fb; // Wrong, why??? 
    pb = fa; // Wrong, but reasonable 

由於fb返回類型可以很好地丟棄(即調用fb()上,無需使用它的返回值) ,爲什麼標記行不起作用?

爲此編譯器仍然抱怨。

void* fa(void); 
    int* fb(void); 
    void* (*pa)(void); 
    int* (*pb)(void); 

    pa = fa; pb = fb; // OK 
-> pa = fb; // Wrong, why??? 
    // pb = fa; 

[Error] invalid conversion from 'int* (*)(void)' to 'void* (*)(void)' [-fpermissive] 

我完全不知道爲什麼......

+3

這是錯誤的,因爲它們是不同的類型。此外,C++略微減少了一般'void *'成語的範圍。早在C的時代,爲了方便,你必須在很多情況下使用'void *'。 C++不鼓勵使用'void *',並強調適當的類型安全設計。無論你想在這裏做什麼,這是錯誤的。您需要弄清楚如何以100%類型安全的方式正確實施您正在做的事情,而不會混淆'void *'。 –

+1

目前還不清楚第一段代碼與其他代碼有什麼關係。請注意,「無效」在任何地方都不意味着同樣的東西 - 在'void *'中它意味着「任何東西」,但它本身意味着「無」。 – molbdnilo

+0

@molbdnilo此代碼'int * f(void); void *(* pf)()= f;'使編譯器抱怨'[錯誤]從'int *(*)(int)'無效轉換爲'void *(*)(int)'[-fpermissive]'。 – iBug

回答

2

即使你的源代碼忽略返回的值,它仍然從函數返回時,它被稱爲和編譯器生成代碼來處理它。
換句話說:它只在源代碼中被忽略,而不是被執行程序忽略。

如果你有

int fa() {return 0;} 
//... 
something(); 
fa(); 
somethingelse(); 

如果pa = fb允許它相當於

int fa() {return 0;} 
//... 
something(); 
{ // Scope that delimits the returned value's lifetime. 
    int imgonnaignorethismmkay = fa(); 
} // End special scope, destroy the return value. 
somethingelse(); 

,就沒有辦法知道的編譯器,有一個返回值,它需要擺脫如果你打電話給pa()


關於第三個情況:

「的函數,返回int*」完全無關「的函數,返回void*
你會看到相同的錯誤,如果你嘗試

char f(); 
int(*p)() = f; 
。即使可以將char轉換爲int,也可以使用

0

函數返回一個int不是一個返回void的函數。你可以調用一個函數並忽略它的返回值,但是當你創建一個指向函數的指針時,類型必須完全匹配。要使用返回int的函數在需要返回void的上下文中,請使用std::function;它處理參數和返回類型中的阻抗不匹配。

相關問題