최근에 완전히 이해할 수없는 함수 포인터와 관련하여 C++에서 비헤이비어가 발생했습니다. 나는 경험 많은 동료와 마찬가지로 Google에 도움을 요청했지만 도움을 줄 수는 없었다.C++에서 함수 포인터를 캐스팅 할 때 이상한 동작이 발생했습니다.
다음 코드는이 신비의 동작을 전시 :
class MyClass{
private:
int i;
public:
MyClass(): i(0) {}
MyClass(int i): i(i) {}
void PrintText() const { std::cout << "some text " << std::endl;}
};
typedef void (*MyFunction) (void*);
void func(MyClass& mc){
mc.PrintText();
}
int main(){
void* v_mc = new MyClass;
MyFunction f = (MyFunction) func; //It works!
f(v_mc); //It works correctly!!!
return 0;
}
그래서, 처음에는 (특히,이 멤버 메소드 PrintText
이다) 나중에 사용하는 간단한 클래스를 정의합니다. 그런 다음 이름 개체 void (*) (void*)
을 MyFunction
- 하나의 void*
매개 변수가있는 함수에 대한 포인터로 정의하고 값을 반환하지 않습니다.
그런 다음 MyClass
개체에 대한 참조를 허용하는 함수 func()
을 정의하고 해당 메서드 PrintText
을 호출합니다.
마지막으로 마술은 주 기능에서 발생합니다. 동적으로 새로운 MyClass
개체에 대한 메모리를 할당하여 반환 된 포인터를 void*
에 캐스팅했습니다. 그런 다음 func()
포인터를 MyFunction
포인터로 캐스팅합니다.이 모든 컴파일을 기대하지는 않지만 그렇습니다. 기본 기능 (func()
가) MyClass
객체에 대한 참조를 허용하더라도
그리고 마지막으로, 나는 void*
인수으로 새로운 개체를 호출. 모든 것이 올바르게 작동합니다!
이 코드를 Visual Studio 2010 (Windows)과 XCode 5 (OSX)로 컴파일하려고 시도했는데 같은 방식으로 작동합니다. 아무런 경고도보고되지 않습니다. 이 작동하는 이유는 상상이 C + +를 참조 실제로 장면 뒤에 포인터로 구현되어 있지만 이것은 설명이 아닙니다.
누군가가이 동작을 설명 할 수 있기를 바랍니다.
코드에 버그 (다른 유형을 가리 키도록 캐스팅 된 포인터를 참조 해제)가 있습니다. 버그를 수정하면 신비가 사라질 것입니다. 예, 버그가있는 코드는 예상 한대로 작동하지 않습니다. 그것이 버그를 발견했을 때 수정해야하는 이유입니다. –
캐스트가 경고/오류를 숨 깁니다. 이것은 '오류 : void (*) (MyClass &)'에서 'MyFunction {aka void (*) (void *)}'[-fpermissive] 로의 잘못된 변환입니다. 컴파일러의 진단을 무시하지 마십시오. –
@remyabel 음, 캐스트가 완벽하게 합법적입니다 (그래서'reinterpret_cast'가 될 것입니다). – Angew