2012-03-04 5 views
4

나는 다음과 같은 코드가 있습니다. 표준 "캐스팅없이 int에서 포인터를 만듭니다"라는 경고가 나타납니다. 다음과 같이 컴파일 할 수있게하려고합니다 :long 함수 포인터를 전송 하시겠습니까?</p> <pre><code>long fp = ... void (*ptr)(long, char*, char*) = fp; </code></pre> <p>긴 <code>fp</code> 긴로 제공되는 정확한 함수 포인터입니다 :

-std=iso9899:1990 -pedantic-errors 

이 경고 메시지가 오류로 바뀝니다. 문제는 올바른 캐스트가 무엇입니까? 다양한 추측을 시도했습니다. 예 :

void (*ptr)(long, char*, char*) = (void)(*)(long, char*, char*) fp; 

하지만 올바른 것을 찾을 수 없습니다.

+0

왜이 작업을 수행 하시겠습니까? –

+0

왜 내가 무엇을하고 싶습니까? – gubby

+0

정수와 함수 포인터 사이에 캐스트 할 수 있습니까? –

답변

7

은 "올바른"캐스트는 다음과 같습니다

void (*ptr)(long, char*, char*) = (void (*)(long, char*, char*))fp; 

물론,이 적절한 형식 정의와 정돈 할 수 있습니다.

하지만 어느 쪽이든 그 결과는 구현에 따라 결정됩니다. 가능한 경우이를 피하고 포인터를 포인터 유형으로 유지하십시오. 가능한 경우 intptr_t을 사용하는 것이 가장 좋습니다.

void (* ptr)(long, char, char *) = (void (*)(long, char, char *))fp; 

하지만 내 제안은 typedef를 사용하고이 모든 혼란에 대해 잊지하는 것입니다 :

typedef void (* fnPtr)(long, char, char*); 
fnPtr ptr = (fnPtr) fp; 
+0

@KerrekSB : 어떤 의미로? –

+0

아니, 괜찮아. 괜찮아! –

7

아마 뭔가처럼 오히려 이진 표현을 복사하십시오 :

long fp; 
void (*ptr)(long, char*, char*); 

memcpy(&ptr, &fp, sizeof ptr); 
+0

예, typedef를 사용하는 것은 올바른 방법입니다 – slashmais

4

유일한 "올바른"방법은 전혀 캐스팅하지

+0

sizeof (long)! = sizeof (ptr) 일 때 대격변이 실패한다는 것 외에는 예외입니다. –

2

여기서 가장 큰 문제는 ANSI-C는 무수한 C-API가이 기능에 의존하고 있음에도 불구하고 이것을 허용하지 않습니다. 따라서 -pedantic으로 컴파일 할 때 문제가 발생할 가능성이 큽니다. 다른 포스터에서 암시 한 것처럼 캐스팅 할 때는 memcpy() 또는 공용체 형식을 사용하여 캐스트를 속일 수 있습니다.

그런데 POSIX는 이것이 작동한다는 것을 보장하므로 '구현 정의 결과'에 관한 부분은 훨씬 덜 무서워집니다.

+0

팁 주셔서 감사. – gubby

+0

C99에서 명시 적으로 허용하지만 결과가 구현에 정의되어 있음을 나타냅니다. –

+0

쿨, 나는 그것을 몰랐다. 저는 주로 C++입니다. 그래서 나는 af89가 그것을 허용하지 않은 C89를 더 잘 알고 있습니다. – ComicSansMS