Почему в этом коде C алфавит разделен на несколько диапазонов?

В пользовательской библиотеке я увидел реализацию:

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'));
}

person Vladimir Ch.    schedule 05.05.2015    source источник
comment
Обратите внимание, что в EBCDIC диапазон символов для строчных букв предшествует диапазону символов для прописных букв, и оба идут перед цифрами, что прямо противоположно порядку в кодировках на основе ASCII (таких как 8859- x, или Unicode, или CP1252, или…).   -  person Jonathan Leffler    schedule 06.05.2015
comment
Примечание: если 'J' - 'I' и 'S' - 'R' оба равны 1, то я ожидаю, что разумный оптимизатор превратит первое во второе.   -  person Matthieu M.    schedule 06.05.2015


Ответы (2)


Вероятно, автору этого кода в какой-то момент пришлось поддерживать EBCDIC, где числовые значения букв не являются смежными ( пробелы существуют между I, J и R, S, как вы могли догадаться).

Стоит отметить, что стандарты C и C++ гарантируют, что символы от 0 до 9 имеют непрерывные числовые значения именно по этой причине, поэтому ни один из этих методов не соответствует строго стандарту.

person Wintermute    schedule 05.05.2015
comment
Да, это уверено, что автор хочет поддерживать код EBCDIC 037. чтобы проверить коды EBCDIC, перейдите по ссылке en.wikipedia.org/wiki/EBCDIC_037. - person Mohit Thakur; 05.05.2015
comment
Да, ты прав. Метод реализован для несмежных букв в EBCDIC. Спасибо за ответ! - person Vladimir Ch.; 05.05.2015
comment
Настоящий WTF — это то, почему первоначальный автор не добавил комментарий: // In the EBCDIC coding, the alphabet has gaps between these values. See URL: xxxx for details. Тогда вам даже не придется задавать вопрос. У вас будет ответ, встроенный в код. - person abelenky; 05.05.2015
comment
@abelenky Если код изначально был для системы, в которой обычно используется ebcdic, в то время он мог показаться очевидным и не нуждался в комментариях, к сожалению, вещи, которые кажутся прекрасными в устаревшем коде, теперь кажутся странными. - person Vality; 05.05.2015
comment
@abelenky: настоящий WTF заключается в том, почему первоначальный автор не использовал стандартную функциональность, то есть return ( isalpha( chValue ) && isupper( chValue ) )... - person DevSolar; 06.05.2015
comment
Есть ли вообще на любой машине, использующей EBCDIC, компилятор C++? Насколько мне известно, ни один компьютер, построенный после ~ 1970 года, не использует это... :-) - person Damon; 06.05.2015
comment
@Damon: Это не проблема. Возможно, вам придется обработать чужую кодировку даже в системе, которая изначально не использует эту кодировку. Таким образом, вы устанавливаете свою локаль на заданную кодировку, а затем вам нужно скрестить пальцы за то, что программист на самом деле использовал стандартные функции вместо умного кодирования, как описано выше, думая, что он знает каждую кодировку, с которой когда-либо столкнется его программа... - person DevSolar; 06.05.2015
comment
Если он был написан для поддержки EBCDIC с 1970-х годов, были ли isalpha и isupper даже ANSI или поддерживались тогда большинством компиляторов? - person nickalh; 06.05.2015
comment
@abelenky не совсем; это явно зависит от диапазонов, которые существуют в используемых кодировках. Это, конечно, не больше WTF, чем второй фрагмент кода в вопросе. - person Jon Hanna; 06.05.2015
comment
@Damon: я считаю, что мэйнфреймы IBM все еще используют EBCDIC, по крайней мере, в режимах совместимости, но, вероятно, по умолчанию. Ваша дата отсечки по крайней мере на 30 лет раньше, а может и больше. - person Jonathan Leffler; 06.05.2015
comment
@DevSolar: На самом деле isalpha неправильно; его результаты зависят от локали и предназначены для обработки естественного языка в настроенной пользователем локали, тогда как фактическая потребность большинства программ состоит в том, чтобы соответствовать фиксированному набору символов, независимому от локали. - person R.. GitHub STOP HELPING ICE; 07.05.2015
comment
@R.: По моему опыту, фактическая потребность для большинства программ состоит в том, чтобы сопоставлять содержимое слов или подобное, и программист просто полностью забыл о проблемах с локалью... в любом случае комментарий подойдет много хорошего. ;-) - person DevSolar; 07.05.2015

Похоже, он пытается охватить как EBCDIC, так и ASCII. Ваш альтернативный метод не работает для EBCDIC (у него есть ложные срабатывания, но нет ложных отрицаний)

C и C++ делают требуют, чтобы '0'-'9' были непрерывными.

Обратите внимание, что вызовы стандартной библиотеки do знают, работают ли они в ASCII, EBCDIC или других системах, поэтому они более переносимы и, возможно, более эффективны.

person MSalters    schedule 05.05.2015
comment
std::isupper фактически запрашивает текущую установленную глобальную локаль C. - person Lingxi; 05.05.2015
comment
Да, ты прав. Метод написан для покрытия обеих кодировок. Спасибо за ответ! - person Vladimir Ch.; 05.05.2015
comment
@Lingxi: Верно, но это не значит, что вы можете переключить язык с ASCII на EBCDIC. 'A' должен оставаться 'A' независимо от локали. ASCII в UTF-8, это было бы возможно. - person MSalters; 05.05.2015
comment
@Lingxi: std::isupper запрашивает текущую установленную глобальную локаль C, да, но фаза компиляции, которая интерпретирует символьные литералы, этого не делает. - person Lightness Races in Orbit; 05.05.2015
comment
@Lingxi - Просто заметка. Сомнительно, действительно ли std::isupper нужен в большинстве случаев. Он учитывает локали, используемые для ввода пользователем. Но при разборе файлов, взаимодействии с базами данных вы обычно ожидаете какую-то другую локаль. Более того, по крайней мере, в Linux эти вызовы, связанные с локалью, очень медленные - например, std::isalpha вызывает dynamic_cast два раза, чтобы найти правильную реализацию локали перед фактическим сравнением одного символа. - person ibre5041; 06.05.2015