2011-12-31 2 views
1

표준 C++에서 이벤트 처리 및 이벤트 선언에 대한 학습을 ​​목적으로 테스트 용으로 작은 라이브러리를 구현하고있었습니다.함수 포인터는 서명과 관계없이 작동합니까? Surprise

내 생물을 고생 및 디버깅 한 후 얼마 지나지 않아 작업이 완료되었습니다 !! 여기

샘플 결국 코드 :

#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'에 대한 스텁 (stub)을 제공하고'event' 물건 만 드롭하면됩니다. – Flexo

+2

@ildjarn 그게 답이 아니라 주석입니다. –

답변

3

이 : 그것은 문법적으로 동일합니다

:

EventHandler(x) 

은 주조 작업입니다 그래서 당신은 X를 캐스팅 캐스트 연산자를 사용하는

((EventHandler)x) 

(INT (*) (int))에서 EventHandle (void (*)())

캐스트 작업은 경고없이 수행됩니다. 기본적으로 컴파일러에게 말하고있다 :
"I know better than you what is actually going just believe me OK!".

기본 emit()은 매개 변수없이 가리키는 함수를 호출합니다.
이것은 좋지 않습니다.

함수 X()에없는 매개 변수가 필요합니다. ABI에 따라 호출 된 함수가 정리할 수 있습니다 (아마도 좋지 않습니다), 운 좋게도 X는 매개 변수를 사용하지 않으므로 정의되지 않았습니다.

함수 X()는 값을 반환한다고 가정합니다 (그렇게하지 않으면 정의되지 않은 동작입니다). 그러나 호출 함수는 반환 값을 기대하지 않으므로 중요한 데이터를 덮어 쓸 수있는 ABI에 따라 정의되지 않은 동작이됩니다.

+0

감사합니다. 내 상황에 유익했습니다. – codekiddy

관련 문제