이 C 코드에서 알파벳이 여러 범위로 분리되는 이유는 무엇입니까?


161

사용자 정의 라이브러리에서 구현을 보았습니다.

inline int is_upper_alpha(char chValue)
{
    if (((chValue >= 'A') && (chValue <= 'I')) ||
        ((chValue >= 'J') && (chValue <= 'R')) ||
        ((chValue >= 'S') && (chValue <= 'Z')))
        return 1;
    return 0;
}

인가요 부활절 달걀 또는 표준 C / C ++ 방법 대 장점은 무엇입니까?

inline int is_upper_alpha(char chValue)
{
    return ((chValue >= 'A') && (chValue <= 'Z'));
}

EBCDIC에서 소문자의 문자 범위는 대문자의 문자 범위보다 앞에오고 둘 다 숫자 앞에옵니다. 이는 ASCII 기반 인코딩의 순서와 정확히 반대입니다 (예 : 8859- x 시리즈 또는 유니 코드 또는 CP1252 또는…).
Jonathan Leffler

1
참고 : 경우 'J' - 'I''S' - 'R'모두 동일 1, 그때는 합리적인 최적화 후자에서 전자를 켜 것이라고 기대합니다.
Matthieu M.

답변:


214

이 코드의 작성자는 아마도 문자의 숫자 값이 연속적이지 않은 지점에서 EBCDIC 를 지원 해야했을 것입니다 (추측 할 수 있듯이 I, JR, 사이에 간격이 S있습니다).

C 및 C ++ 표준 은 이러한 이유로 정확하게 문자 가 인접한 숫자 값 09갖도록 보장 하므로 이러한 방법 중 어느 것도 엄격하게 표준을 준수하지 않습니다.


64
실제 WTF는 왜 원저자가 주석을 달지 않은 이유 // In the EBCDIC coding, the alphabet has gaps between these values. See URL: xxxx for details입니다. 그렇다면 질문을 할 필요조차 없습니다. 코드에 대한 답변이 기본 제공됩니다.
abelenky

66
@abelenky 코드가 원래 ebcdic이 일반적으로 사용되는 시스템을위한 것이면 당시에는 분명해 보였고 주석이 필요하지 않았지만, 불행히도 레거시 코드에서 잘 보이는 것이 이상하게 보입니다.
Vality

26
@abelenky : 실제 WTF는 원래 작성자가 표준 기능을 사용하지 않은 이유입니다 return ( isalpha( chValue ) && isupper( chValue ) ).
DevSolar

4
@Damon : 문제가 아닙니다. 해당 인코딩을 기본적으로 사용하지 않는 시스템에서도 "외계인"인코딩 을 처리 해야 할 수도 있습니다 . 따라서 로케일을 주어진 인코딩으로 설정 한 다음 프로그래머가 위와 같이 "스마트 한"코딩을 수행하는 대신 표준 기능을 실제로 사용했다는 점을 간과해야합니다.
DevSolar

6
1970 년대부터 EBCDIC를 지원하도록 작성된 경우 isalpha와 isupper는 ANSI 였거나 당시 대부분의 컴파일러에서 지원 되었습니까?
nickalh

54

EBCDIC과 ASCII를 모두 다루려고하는 것 같습니다. 대체 방법이 EBCDIC에서 작동하지 않습니다 (오탐 (false positive)는 있지만 오탐 (false negative) 없음)

C와 C ++ 것을 요구 '0'-'9'연속이다.

표준 라이브러리 호출 ASCII, EBCDIC 또는 기타 시스템에서 실행되는지 여부를 알고 있으므로 이식성이 뛰어나고 더 효율적입니다.


5
std::isupper실제로 현재 설치된 전역 C 로캘을 쿼리합니다.
링시

1
네, 맞아요. 이 방법은 두 가지 인코딩을 모두 다루기 위해 작성되었습니다. 답변 해주셔서 감사합니다!
블라디미르

4
@Lingxi : True이지만 로케일을 ASCII에서 EBCDIC으로 전환 할 수있는 것은 아닙니다. 로캘에 관계없이 'A'남아 있어야 'A'합니다. ASCII에서 UTF-8까지 가능합니다.
MSalters

2
@Lingxi : std::isupper현재 설치된 전역 C 로캘을 쿼리하지만 문자 리터럴을 해석하는 컴파일 단계는 그렇지 않습니다.
궤도에서 가벼움 경주

1
@Lingxi-빠른 참고. std::isupper대부분의 경우 실제로 필요한지 여부는 의문 입니다. 사용자 입력에 사용되는 로케일을 존중합니다. 그러나 파일을 구문 분석 할 때 데이터베이스와 상호 작용하면 일반적으로 다른 로케일이 필요합니다. 또한 적어도 리눅스에서는 이러한 로케일 관련 호출이 매우 느리다. 예를 들어 std::isalphadynamic_cast를 두 번 호출하여 단일 로케일을 실제로 비교하기 전에 적절한 로케일 구현을 "찾기"합니다.
ibre5041
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.