2009-03-20 2 views
7

가능한 중복 : 나는 R.포인터 타입 불일치 경고

K &하여 C 프로그래밍 언어를 통해 내 방식대로 일하고있다
Problem compiling K&R example

최근

섹션 5.11에서는 함수에 대한 포인터와 해당 예제에서 입력 한 후의 포인터를 다룹니다. 빠른 구현으로 compari에 대한 포인터를 제공합니다 우리가 사용하고자하는 자식 함수 - 조건부 표현식에서 포인터 유형이 일치하지 않는다는 경고가 컴파일러에서 발생했습니다. 경고를 트리거의 예에서

라인한다 (제 컴파일러는 OS X 10.5.6에 GCC 4.0.1이다) :

qsort((void **) lineptr, 0, nlines-1, 
     (int (*)(void*, void*))(numeric ? numcmp : strcmp)); 

이 프로그램은 segfaulting없이 실행,하지만 난 모든 경고를 smoosh 좋아 적어도 그 원인을 이해할 수 있습니다.

int numcmp(char *, char *); 

그러나 맨에 따르면, stcmp이 서명이 있습니다 :

int strcmp(const char *s1, const char *s2); 

인가가 있기 때문에 약간 다른 방법 서명의 간단한 경고

는 numcmp에 대한 함수 선언처럼 보인다? 경고를 무시할 때의 결과는 무엇입니까?

+0

에디는 속임수를 지적했습니다. 나는 내 자신의 질문을 끝내기로 결심했지만 소유자가 간단히 닫을 수있는 방법이있을 것이라고 생각했습니다. – Dana

+0

Dana, [K & R 예를 컴파일하는 데 문제가 있음] (http://stackoverflow.com/questions/616906/problem-compiling-kr-example/616929)을 확인하십시오. 그러면 질문에 대한 답을 찾을 수있을 것입니다. 그렇지 않으면 알려주십시오. – Eddie

답변

1

표현식을 시도하고 진단하는 한 가지 방법은 표현식을? :로 바꾸면 두 가지 중 하나만 수행하면 어떻게되는지 확인하는 것입니다.

stmcmp가 아닌 numcmp에서만 발생하는 경우 const char *가 원인 일 수 있습니다. char *는 항상 void *로 변환 할 수 있지만 const char *를 void *로 "안전하게"변환 할 수는 없다고 생각합니다.

두 경우 모두, 아마도 이것은 char *를 void *로 변환하는 기능 포인터와 관련하여 약간의 문제가 있지만 서명은 동일해야하며 문자 대신 공백이 문제가됩니다.

3

짧은 답변 : K & R은 C를 몰랐

긴 대답 : 그들은 그들이 시작했을 때, 아무도이 C 몰랐다는 사실에 의해 장애인 있었다, 그래서 그들은 일종의으로 그것을 만들고 있었다 그들은 따라 갔다.

(약간) 긴 답변을 덜 경박 형태 : K & R이 기록 된 이후 꽤 (일부 을 변경 말할 것입니다)하지만, 언어는 진화했다 당신은 동적 예와 함께 전자 책 버전을 가지고하지 않는 한 모핑 (morphing)하면 K & R의 예제는 "새롭고 승인 된"("지금 ANSI!가 더 많이!") 언어를 따라 잡을 수 없습니다.

7

char *를 void *로 내재적으로 캐스팅 할 수 있지만 이러한 유형의 함수 포인터에 대해서는 (경고없이) 동일한 작업을 수행 할 수 없습니다. 컴파일러는 함수 시그니처에 대한 유형 일치에보다주의를 기울입니다.

qsort 내부에서 일어나는 일은 반대가 될 것입니다. 즉, void *는 numcmp의 char * 및 strcmp의 const char *에 캐스팅됩니다.

그리고 이러한 경우 컴파일러에서 경고를 발행해야합니다. 매개 변수와 같은 유형이없는 함수를 사용해야하는 경우 유형과 일치하는 래퍼 함수를 ​​사용하고 원래 함수를 호출 할 때 적절한 명시 적 형변환을 수행해야합니다. 예를 들어

:

static int strcmp_wrapper(void* s1, void* s2) { 
    return strcmp((char*)s1, (char*)s2); 
} 

static int numcmp_wrapper(void* n1, void* n2) { 
    return numcmp((char*)n1, (char*)n2); 
} 

qsort((void **) lineptr, 0, nlines-1, 
     (numeric ? numcmp_wrapper : strcmp_wrapper)); 

을 그리고 qsort를위한 현대적인 서명 const의 문제가 귀하의 질문에 활동하기 시작하는 것 같지 않지만, K & R은하지 않았다

void 
qsort(void *base, size_t nel, size_t width, 
     int (*compar)(const void *, const void *)); 

입니다 const 있습니다.

+0

또 다른 옵션은 삼항 식을 다음과 같이 변경하는 것입니다. numeric? (int (*) (void *, void *)) numcmp : (int (*) (void *, void *)) strcmp); 그래서 두 개의 다른 함수를 qsort에 별도로 전달하십시오. 이렇게하면 컴파일러에서 제공하는 경고도 피할 수 있습니다. – bryanph