2011-12-31 11 views
1

標準的なC++でのイベント処理とイベントの宣言について、テスト目的で小さなライブラリを実装していました。関数ポインタは署名に関係なく機能しますか?サプライズ

私の生き物を苦労してデバッグしていたのですが、ついにそれが効きました!!ここで

は、サンプルコードでは、結局次のとおりです。

#include "Event.h" 
#include "Handler.h" 
using namespace System; // lol yeah, I wrapped all into namespace called System (like .NET) :D 

//this is the actual event trigger function: 
int x(int) { 
    Write "event!!"; 
    return 0; 
} 
    typedef void (*EventHandler)(); //this is funny(pointer to int(*)(int) 


//simple implementing new keywords: (macros and typedefs) 

int main() { 
    event test; //new event 
    Handler hnd(test, EventHandler(x)); // EventHandler takes void(*)() NOT int(*)() !!! 
    emit(test); //raise event triggers the x function with no problem 
    return 0; 
} 

それがエラーなしでコンパイルどのように来ます?

私はすべてのコードを貼り付けますが、それは複雑だ

...

私の質問です:私はちょうど良い方法typedefEventHandler作品の混乱していますか?

"イベントトリガ機能"の署名に関係なく、コンパイル出力は問題なく、エラーはありません。

+8

'EventHandler(x)'は '(EventHandler)x'と同じです。あなたは 'x'を別の型として扱うようにコンパイラを強制しています。なぜコンパイルしないのですか? – ildjarn

+1

* "私はすべてのtHEコードをペーストしますが、それは複雑です" * - 読者とあなた自身の両方にとってより有用なのは、最小限の完全な例を構築することです。あなたが示したコードからは、 'Handler'のためにスタブを与え、' event'ものだけを落とす必要があるようです。 – Flexo

+2

@ildjarnそれは答え、コメントではありません。 –

答えて

3

は、この:それは構文的に同等である

EventHandler(x) 

は、キャスト操作されるように、あなたはXをキャストするキャスト演算子を使用している

((EventHandler)x) 

(int型(*) (void)(*)()

キャスト操作は警告なしで行われます基本的にコンパイラに伝えています:
"I know better than you what is actually going just believe me OK!"

その下にあるemit()は、パラメータなしでポイントされている関数を呼び出すだけです。
これは悪いです。

関数X()が存在しないパラメータを期待しています。 ABIによっては、呼び出された関数がそれを整理することができます(これはおそらくうまくいきません)。幸いなことに、Xはパラメータを使用しません。

関数X()は値を返すことになっています(未定義の動作ではありません)。しかし、呼び出し側の関数は戻り値を期待していないので、重要なデータを上書きする可能性があるABIに依存するような未定義の動作になります。

+0

ありがとう、私の状況に有益だった。 – codekiddy

関連する問題