Почему sys_errlist устарел в glibc?

sys_errlist — это удобный массив, который позволяет получать статические errno описания. Альтернативой ей является функция strerror_r, которая доступна в двух сбивающих с толку несовместимых вариантах. Версия GNU возвращает char *, который будет из того же вышеупомянутого массива, если ошибка известна, или, в противном случае, из предоставленного пользователем буфера. Стандартная версия strerror_r вместо этого возвращает int и всегда использует предоставленный пользователем буфер. Проблема в том, что эти две функции имеют одно и то же имя, несмотря на то, что имеют совершенно разную семантику, поэтому вам в основном нужно выполнить довольно сложную #ifdef проверку и написать две совершенно разные версии вашего кода в зависимости от того, какую версию вы получите. Вдобавок к этому обе эти функции хуже, чем sys_errlist, так как обе требуют от вызывающей стороны предоставления «достаточно большого» буфера для хранения описания, даже если версия GNU редко использует его, и ни одна из функций не позволяет узнать только насколько большим должен быть буфер. Если вместо этого вы решите использовать sys_errlist вместо этого, вы можете просто проверить, есть ли value >= sys_nerr, и выделить буфер только в этом случае, просто поместить туда Unknown error %d через snprintf, и готово.

Учитывая, что strerror_r — это ужасный, непонятный и неэффективный беспорядок, почему разработчики GNU помечают sys_errlist как устаревшее, фактически вынуждая либо использовать strerrror_r, либо наблюдать уродливое предупреждение каждый раз при компиляции кода?


person dragonroot    schedule 26.11.2015    source источник


Ответы (1)


strerror и его родственники локализованы. Можно спорить о полезности нелокализованного системного сообщения, но сопровождающие glibc придерживались преобладающего направления (Solaris и другие системы).

Однако: sys_errlist уже давно устарел. Это не интерфейс POSIX. В некоторых системах его нет.

Дальнейшее чтение:

Давно это не было проблемой, но раньше в некоторых системах не было strerror (см. Примечания о несовместимости с Unix: функции строк и памяти).

person Thomas Dickey    schedule 27.11.2015
comment
На самом деле это вообще не отвечает на вопрос. sys_errlist является статическим массивом и полностью потокобезопасен. - person Jonathon Reinhart; 27.11.2015
comment
В glibc есть много нестандартных вещей, использование которых, похоже, не сопровождается предупреждениями об устаревании во время компиляции. - person dragonroot; 27.11.2015
comment
Glibc предоставляет тонну интерфейсов, которые не совместимы с POSIX и не объявлены устаревшими. - person Jonathon Reinhart; 27.11.2015
comment
Но в использовании sys_errlis нет ничего, что не было бы потокобезопасным. - person Jonathon Reinhart; 27.11.2015