Может ли isdigit законно зависеть от локали в C - PullRequest
18 голосов
/ 24 мая 2010

В разделе, посвященном setlocale, стандарт ANSI C в сноске гласит, что единственными функциями ctype.h, поведение которых не зависит от текущей локали, являются isdigit и isxdigit.

Реализация isdigit в Microsoft зависит от локали, поскольку, например, в локалях, использующих кодовую страницу 1250, isdigit возвращает ненулевое значение только для символов в диапазоне 0x30 ('0') - 0x39 ('9'), тогда как в локалях при использовании кодовой страницы 1252 isdigit также возвращает ненулевое значение для цифр верхнего индекса 0xB2 ('²'), 0xB3 ('³') и 0xB9 ('¹').

Является ли Microsoft нарушением стандарта C, делая язык isdigit зависимым?

В этом вопросе меня больше всего интересует C90, которому, как утверждает Microsoft, соответствует, а не C99.

Дополнительный фон:

В собственной документации Microsoft о setlocale неправильно указано, что на isdigit не влияет часть LC_CTYPE локали.

Раздел стандарта C, который охватывает функции ctype.h, содержит некоторые формулировки, которые я считаю неоднозначными:

Поведение этих функций зависит от текущей локали. Те функции, которые имеют специфичные для локали аспекты, только если они не в локали "C", отмечены ниже.

Я считаю это неоднозначным, потому что неясно, что он пытается сказать о функциях, таких как isdigit, для которых нет замечаний о специфичных для локали аспектах. Можно попытаться сказать, что такие функции должны зависеть от локали, и в этом случае реализация isdigit от Microsoft будет в порядке. (За исключением того, что сноска, о которой я упоминал ранее, кажется, противоречит этой интерпретации.)

Ответы [ 2 ]

11 голосов
/ 24 мая 2010
  1. Microsoft всегда права.
  2. Если Microsoft не права, см. Пункт 1

У Microsoft всегда есть своя интерпретация спецификации. И обычно предложение «но Microsoft ошибается» не имеет никакого отношения к вашему генеральному директору, поэтому вы должны кодировать ошибки и интерпретации MS.

Количество кода для поддержки некорректного поведения IE и Outlook ошеломляет.

Во многих случаях единственное решение - развернуть собственную версию функции, которая делает правильные вещи, и сделать что-то вроде этого:

int my_isdigit( int c )
{
#ifdef WIN32
  your implementation goes here
#else
  return isdigit( c );
#endif
}
4 голосов
/ 24 мая 2010

Требуемый набор символов определен в разделе 2.2.1. Затем в разделе 2.2.1.2 описывается поведение символов расширения:

  • Должны присутствовать однобайтовые символы, определенные в $ 2.2.1.
  • Наличие, значение и представление любых дополнительных членов зависит от региона.
...