2009-12-04 8 views
22

또 다른 간단한 예 :왜 부정적인 errno를 반환합니까? (예 : return -EIO)

if (wpa_s->mlme.ssid_len == 0) 
    return -EINVAL; 

왜 단항 마이너스입니까? 성공시> 0, 실패시 < (=) 0을 반환하는 함수에 대해이 작업을 수행합니까? 아니면 다른 이유가 있습니까?

+29

우리는 SUCCESS보다 덜 좋아하기 때문에! –

+2

사람들이 질문 제목에 "[C]"라는 태그를 붙이는 이유는 알지 못합니다. 각 질문은 항상 태그가 무엇인지 링크합니다 (예 : 질문에 [c], [errno], [return-value] 태그가 붙어 있습니다) 왜 [ "C] [errno] [return-value] 부정적인 errno를 반환합니까? (예 : return -EIO) " – Pete

+0

질문 제목을보고 즉시 발작이 있었고 심한 혼수 상태가있었습니다. 세계 수준의 두뇌 외과 의사의 빠른 대응 팀이 없다면 언제든지 질문에 대답하기 위해 제 시간에 복구했는지 알 수있는 내 전제가 있습니까? –

답변

13

기본적으로 이유가 있습니다. 많은 함수가 "좋은"긍정적 인 결과를 많이 가지므로 오류 코드에 음의 값을 남깁니다.

C/POSIX 오류 코드는 "역사적으로 커지기"때문에 약간의 운율이나 이유가 너무 많은 것 같습니다.

더 많은 현대 언어에서 오류에 대한 예외가 발생하므로 오류 코드에 대한 가능한 응답 범위의 일부를 납치 할 필요가 없습니다. 물론 트레이드 오프가 있습니다.

+7

적어도 성공으로 정의하고, 문제가 성공적이면 긍정적이며, 실패한 경우는 음수로 정의하는 경향이있었습니다. 적어도 이전의 유닉스 시대에는 그렇습니다. –

7

귀하의 이해가 일반적입니다. 분명한 해석은 올바른 것입니다.

표준 규칙은 수식과 약간 다릅니다. 유닉스에서

, 쉘과 같은 CLI 수준의 유틸리티 사실 또는 성공 0 상태 테스트를 종료하는 프로그램. 도서관에서 -1은 일반적으로 오류를 반환합니다.

>= 0좋은< 0오류 수단 곳은 일반적인 패러다임에 연결됩니다. 이것은 아무 것도 설정되어 있지 않습니다.

BTW, 이것은 sentinel pattern로 분류 할 수 있으며 당신은 감시 반환을 호출 할 수 있습니다. 실제로는 센티널 "값"과 오류 코드가 결합되어있어 한 위치에서 오류 코드를 반환하고 다른 위치에서 오류가 발생하는 경우 센티널 값을 반환하는 것보다 입력하기 쉽고 스레드로부터 안전하기 쉽습니다.

Wikipedia reports that a sentinel value은 루프를 종료하는 데 사용되지만 함수 반환이 훨씬 더 일반적인 인스턴스라고 생각합니다. 어느 누구도 이러한 정의를 정확하게 지키지 않습니다.

17

처음에는 이것이 실제로 C가 아닙니다. 당신은 어떤 목적으로 C로 작성된 함수를보고있다. 동일한 규칙이 모든 언어에서 사용될 수 있습니다.

나의 오래된 유닉스 시대에, 0은 성공을 의미하고, 양수는 사소한 문제를 의미하고, 음수는 일종의 실패를 의미하는 컨벤션이있었습니다. 그러므로, 일종의 if (foo() >= 0) { /* success of a sort */ } 대회도있었습니다.

이것은 의심 할 여지없이 Unix 프로세스 리턴 코드와 관련이 있습니다. 여기서 0은 성공한 것입니다.

+0

비슷한 질문에 당신을 여기에 인용 [유닉스와 리눅스 : "exit 99는 무엇을 의미합니까?"] (http://unix.stackexchange.com/a/125333/11836) – smci

0

최적화 관점에서 음수를 사용하면 Unix 기반 커널이 2 개가 아닌 하나의 비교 만 사용하여 오류 코드를 확인할 수 있습니다.

커널의 함수는 종종 포인터 대신 오류 코드를 반환합니다.즉, 오류 코드는 유효한 포인터 주소와 겹칠 수 없으므로 기본적으로 부호가 가장 낮은 값인 (>= 0) 또는 가장 높은 부호가없는 값 (<= unsigned max)이어야합니다.

NULL의 포인터 값과 오류 코드 확인은 매우 일반적인 작업이므로이를 최적화하는 것이 좋습니다.

은 일반적으로 바닥이있는 < 0x8000NULL 값과 정상 값이 에러 코드 (-10xff...ff, 최대 가능한 부호 값으로 저장된다) 기억된다.

(-MAX_ERRNO -1 마찬가지)

ERRNOx >= (unsigned long)(-MAX_ERRNO) (0 0x8000을위한 진정한)

NULLx <= 0x8000 경우 :

은 각 확인하기 위해 하나 개의 비교를 사용할 수 있다는 것을 의미한다

You can see this happening in Linux's err.h file.

관련 문제