2017-08-04 6 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 *'の使用を控え、適切なタイプセーフな設計を強調しています。ここで何をしようとしていても、間違っています。 'void * 'を使いこなすことなく、あなたがしていることを100%型安全に実装する方法を理解する必要があります。 –

+1

最初のコードと他のコードとの関係は明確ではありません。 "void"はどこでも同じ意味を意味するわけではありません。 "void *"では "anything"を意味しますが、それ自体では "nothing"を意味します。 – 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()に電話した場合のあなたの三番目のケースで


あなたは

char f(); 
int(*p)() = f; 
をしようとした場合、「 void*を返す関数
あなたは、同じエラーが表示されますし、完全に無関係である

int*を返す関数」。

charをintに変換することはできますが、

0

intを返すのはvoidを返す関数ではありません。関数を呼び出してその戻り値を無視することができますが、関数へのポインタを作成するときには、その型は正確に一致する必要があります。 voidを返すものが必要なコンテキストでintを返す関数を使用するには、std::functionを使用します。引数と戻り値の型のインピーダンスの不一致を処理します。

関連する問題