[완료]Pointer to function 부분에서 갑자기 혼란이 옵니다!
글쓴이: soratz / 작성시간: 수, 2011/02/09 - 9:10오후
안녕하세요
APUE 책을 공부하고 있는데요
문득 제 머릿속의 개념이 흔들리는 부분이 있어서
책과 인터넷을 찾아 보았으나
해결이 안되서 이렇게 질문 올립니다.
signal 부분을 보다보니
#define SIG_ERR (void (*) ())-1
#define SIG_DFL (void (*) ())0
#define SIG_IGN (void (*) ())1
이렇게 선언된 부분이 있고
"pointer to a function that takes an integer argument and returns nothing"
이렇게 되있는데요
정수를 받고 void를 리턴하는 함수라면
(void (*) (int)) 이렇게 되야 하는것 아닌지요
저 뒤에 있는 -1, 0, 1 부분이 잘 이해가 되지 않습니다.
그리고 signal 함수의 prototype을 보면
void (*signal(int signo, void (*func)(int)))(int);
이렇게 선언되어있는데
리턴값이 void를 리턴하고 int형 인자를 받는 function 인데요.
직관적으로 제일뒤에 붙은 (int)가 이해가 잘 안되네요
혹시 이 부분에 대해 참조할만한 곳이 있을까요?
부끄럽지만 시간이 되시는 분이 계시면 조언 부탁드립니다 ^^
Forums:
이런 답변이 있네요.
//
http://kldp.org/node/4103
//
답변이 맞는건 같은데;;;;. 알면. 참 좋을텐데... 영어해석이 어렵네요.
http://www.velocityreviews.com/forums/t715007-re-how-to-understand-this-cpp-syntax.html
#define SIG_ERR ((void (*) ())-1)
#define SIG_DFL ((void (*) ())0)
#define SIG_IGN ((void (*) ())1)
Each definition is an integer constant expression converted,
via a cast, to a pointer-to-function type. The cast is to type
``void(*)()'', i.e., pointer to function returning void.
A modern implementation would probably define the
parameter type:
#define SIG_ERR ((void (*) (int))-1)
#define SIG_DFL ((void (*) (int))0)
#define SIG_IGN ((void (*) (int))1)
SIG_ERR, SIG_DFL, and SIG_IGN have to be function pointers, but
they merely have to be unique values; it needn't be possible to
call anything using their values. Converting a constant 0 to a
pointer-to-function type yields a null pointer, so SIG_DFL happens
to expand to an expression that evaluates to a null pointer value;
(SIG_DFL == NULL) is true. Converting any other integer value to
a pointer-to-function type yields some value that's not specified
by the standard (I'm not sure whether it's implementation-defined
or unspecified). The point is that, for the implementation for
which the above definitions were written, the three expressions
yield pointer values that are distinguishable from any pointer to
an actual function.
----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.
매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.
각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com
정말 감사합니다.
제가 미처 함수로는 검색을 못해봤네요 죄송하고 감사합니다.
파라미터가 정해지지 않은 함수 포인터도 있다는 사실에
새삼 놀랍습니다.
그리고 정수가 함수로 캐스팅이 되는것도 몰랐네요
제 무지를 심히 반성합니다 ㅠ
좀 더 고급 책을보면 나오는 내용인가봐요
아무튼 너무 감사합니다 !
그렇지만... 어디까지나 C 에서만 가능한 것이고...
같은 코드라도 C++ 컴파일러로 컴파일 하면 캐스팅이 안됩니다.
즉, C 언어에서는 캐스팅 규칙이 느슨해서 가능했던 것입니다.
C++에서도 사용하려면, 님 질문에서 쓰신 것 처럼 "#define SIG_ERR (void (*) (int))1" 같이 해줘야 합니다.
모두들 행복하세요~
아 그렇군요
이 부분이 많이 사용해보지 않아서인지 몰라도 많이 생소합니다.
또 궁금한게 있는데요 혹시 저렇게 캐스팅된 값이 어떻게 유일하다고 할수 있는거죠?
The three values used for these constants need not be -1, 0, 1. They must be three values that can
never be the address of any declarable function. 이라고 되있는데
다른 -1, 0, 1을 캐스팅한 값이 function의 주소가 되지 않는다는걸 어떻게 확신할 수 있죠?
그리고 지금 검색하다가 봤는데 함수 포인터를 2가지 방법으로 선언할 수 있다고 해서 보니
void (*pf) (int); 이 방법과
void (*) (int) pf; 이 방법이 있다고 하는데
후자는 컴파일 에러가 뜨네요 , 제가 참조한 문서가 잘못된 것인가요?
OS(커널) 관련 질문입니다.
일반적인 OS에서 사용자 프로세스는 취할 수 없는 주소들이 있습니다. 그 중에 -1(0xffffffff) , 0(Null), 1(0x00000000) 등이 포함되겠습니다.
이 부분은 "리눅스 커널 메모리 관리" 문헌을 참고 바랍니다.
두번째 방법 즉 컴파일 오류가 나는 것은 잘못 된 것입니다. 어디서 참고하신지는 모르나 인터넷의 모든 자료가 정확하다고 할 순 없습니다.
캐스팅하는 방법을 잘못 보신것 아닌가요? funcA = (void (*)(int))funcB; 처럼 말이죠.
모두들 행복하세요~
와~
리턴된 포인터 값에 -1(0xFFFFFFFF)의 경우, 메모리 할당 방법상 당연히 불가능하니 이런식으로 사용했구나.. 생각했었는데,
구체적으로 명시되어 있는 부분이었네요..
참고로 NULL이 꼭 0은 아니라네요.
최신 시그널 핸들러 선언은....
아래처럼 되어 있습니다...
/usr/include/asm-generic/signal-defs.h 파일:
리눅스 매뉴얼 페이지를 참고 해보면... "void ( *signal(int signum, void (*handler)(int)) ) (int);" 식의 표현은 읽기가 어려다고 하네요.
모두들 행복하세요~
아 저기에 있었군요!
감사합니다 !
혹시 저 부분을 어떻게 찾으셨나요?
코딩하다가 궁금할때마다 함수 원형을 보려고 찾아보면
원형은 없고 extern 으로 선언된 부분만 있어서 당황한적이 많거든요
어떤 규칙같은게 있을까요?
기본적으로 리눅스 매뉴얼 페이지를 참고 하시면 찾을 수 있습니다.
아래 매뉴얼 페이지에서 SYNOPSIS 항을 보면 signal.h가 있습니다. 일반적으로 사용자 컴파일러 환경에서 헤더 파일들은 /usr/include 경로에서 찾게 됩니다.
따라서 /usr/include/signal.h에 있습니다. /usr/include 경로 밑에 하위 디렉토리들이 다수 있는데 결국 따라가다 보면 필요한 정보를 얻을 수 있습니다.
각각의 하위 디렉토리는 인터넷에서 자료를 찾으시면 참고할 만한 문헌들을 찾을 수 있을 겁니다.
모두들 행복하세요~
댓글 달기