2010-07-01 4 views
4

나는 C 프로그램을 만들고있다. 두 개의 포인터 인수를 취하고 복잡한 연산을 수행하는 함수가 있습니다. 'cmp'라고 해봅시다. 설명을 위해 cmp()는 결코 복잡하지 않습니다.GCC 경고에 대한 해결 방법을 얻으려면 "XXX의 주소가 절대 NULL이 아닙니다"?

 
int cmp(struct foo *a, struct foo *b) { 
    return (a->bar == b->bar); 
}

나는이처럼 NULL 검사 매크로를하고 싶습니다 :

 
#define SAFE_CMP(a,b) ((a) != NULL && (b) != NULL) ? cmp(a,b) : 0 

나는이 완벽하게 정상적으로 생각합니다. 그러나 오류로 경고를 간주 -Wall의 컴파일시 스위치에서, 다음과 같은 코드가 골치 : GCC는이 상황을 해결하기 위해 어떤 방법이 있나요 "the address of b will never be NULL".

경고

 
int baz(struct foo *a) { 
    struct foo b; 
    ... 
    return SAFE_CMP(a, &b); 
}

때문에? SAFE_CMP_1(safe_arg,unsafe_arg), SAFE_CMP_2(unsafe_arg,safe_arg) ... 등, 다양한 헬퍼 매크로를 가지는 것은 내가 원하는 마지막 것입니다. 모든 상황에 대해 하나의 도우미 매크로를 appricable하게하고 싶습니다.

미리 감사드립니다.

#define SAFE_CMP(a,b) ((void *)(a) != NULL && (void *)(b) != NULL) ? cmp(a,b) : 0 

을 ...하지만 개인적으로, 난 그냥 함수 자체 safe_cmp()을 만들 것입니다 :

철 웅 양

+0

GCC pragma 중 하나를 사용하여 매크로의 Null-Check 부분에 대한 경고를 비활성화 한 다음 다시 활성화 할 수 있습니다. –

+3

나는 이것이 당신을 사는지 알지 못합니다. 'cmp()'함수가 왜 이런 체크를 할 수 없는지? – BobbyShaftoe

답변

9

이 나에게 경고를 억제하는 것으로 보인다.

int safe_cmp(struct foo *a, struct foo *b) { 
    return (a && b) ? (a->bar == b->bar) : 0; 
} 
+0

내 실제 작업 소스에서 cmp()도 _macro_입니다. 인라인 함수를 작성하는 것이 더 좋습니다. 매우 고마워. [ –

+0

내가 할 수 있으면이 게시물을 한 번 이상 투표 하겠어! 이 경고는 나에게 두통을 일으켰고, (무효 *) 캐스트 트릭은 그저 그날을 구할지도 모른다. – m01

+0

덧붙여 말하자면, 경고를 억제하기 위해 다른 포인터 유형으로도 타입 변환 할 수있는 것처럼 보입니다. – m01

2

"나는 매크로 appricable 모든 상황을 한 도우미를하고 싶습니다."

왜? 하나의 크기가 모두에 맞지는 않습니다. GCC는 당신에게 비교를 말함으로써 당신에게 호의를 베풀고 있습니다 항상은 어떤 결과가 있습니다. 스택 변수의 주소는 이 아니며이 NULL이 아닙니다. 난 그냥 바즈에서 체크 아웃을 작성합니다

int baz(struct foo *a) { 
    struct foo b; 
    ... 
    return a == NULL ? 0 : cmp(a, &b); 
} 

또한 cmp에서 할 수 있습니다. 사전 조건과 사후 조건을 정의하는 방법에 따라 다릅니다.

매크로 (baz에는 해당되지 않음)의 다른 가능한 문제점은 ab이 여러 번 평가된다는 것입니다. 의주의 :

SAFE_CMP(p++, p1++); 
+0

나는 그것이 맛의 문제라고 생각한다.개인적으로 올인원 방식을 선호합니다. 두 개의 동적 포인터 값을 전달할 때마다 gcc가 null을 확인하면 기쁠 것입니다. 그러나 그 매크로를 사용하여 정적 포인터 값을 전달할 때 gcc가 이러한 성가신 경고를 확인하지 않도록하고 싶습니다. 분명히 "반환 SAFE_CMP (a, &b);"는 "a == NULL을 반환하는 것보다 명확하고 읽기 쉽습니다. 0 : cmp (a, &b);" 어쨌든 친절한 답장을 보내 주셔서 감사합니다. –

0

GCC 옵션 -Wno-address이 경고를 제거하는 것 같다.