Реализации языка C имеют значительные отличия. ANSI C уменьшает
эту несовместимость, но не позволяет ее избежать полностью; между тем,
многие пользователи желают компилировать программное обеспечение GNU с
помощью компиляторов, реализующий до-ANSI версию языка C. Эта глава
дает рекомендации, как использовать более или менее стандартные
библиотечные функции C, чтобы избежать нежелательной потери
переносимости.
Не используйте значение sprintf. Она возвращает количество
выведенных символов на некоторых, но не на всех системах.
Не описывайте системные функции явно. Почти любое описание
функции будет неверным в некоторой системе. Чтобы минимизировать
конфликты, следует использовать системные заголовочные файлы для
описания системных функций. Если заголовочный файл не описывает
функцию, оставте ее неописанной. Хотя использование функции без
описания и выглядит неаккуратным, на практике это работает хорошо для
большинства систем, в которых такая ситуация возникает. Эта проблема
только теоретическая. Напротив, наличие явного описания как правило
приводит к конфликтам.
Если Вы должны описать системную функцию, не указывайте типы ее
аргументов. Используйте описания в старом стиле, не ANSI-прототипы.
Чем больше Вы укажете про функцию, тем скорее возникнет конфликт.
В частности, никогда не надо объявлять malloc или realloc.
Большинство GNU-программ используют эти функции только однажды, в
функциях, которые названы соответственно xmalloc и xrealloc. Эти
функции вызывают malloc и realloc соответственно, и проверяют их
результат. Поскольку xmalloc и xrealloc определены в Вашей программе,
Вы можете описать их в других файлах без какой-либо опасности
конфликта. На большинстве систем, int имеет такую же длину, как и
указатель, поэтому вызовы malloc и realloc работают правильно. Для
некоторых систем-исключений (большинство 64-разрядных машин), Вы
можете использовать описания malloc и realloc - или поместить описания
в конфигурационные файлы, специфичные для этих систем.
Строковые функции требуют специального использования. Некоторые
Unix-системы имеют заголовочный файл 'string.h', некоторые
'strings.h'. Ни то, ни другое имя файла не переносимо. Вы можете \
сделать две вещи: использовать Autoconf, чтобы определить, какой файл
следует использовать, либо не включать ни один из этих файлов.
Если Вы не включаете ни один из этих файлов, Вы не можете
получить описания для функций обработки строк обычным способом. Это
приводит не к таким большим проблемам, как можно подумать. Новые
строковые функции, согласованные с ANSI, выходят за наше рассмотрение,
поскольку они не поддержаны на многих системах. Вы можете использовать
следующие строковые функции:
Функции копирования и конкатенации работают хорошо без описания,
если не используются возвращаемые значения. Использование значений без
описания не работает на системах, где ширина указателя отличается от
ширины int, и в некоторых других случаях. Использования значения этих
функций легко избежать.
Функции сравнения и strlen нормально работают на большинстве
систем, возможно на всех, на которых GNU-программы работают. Вы можете
найти нужным объявить их на некоторых системах.
Функции поиска должны быть описаны как возвращающие char *. К
счастью, нет различий в возвращаемом типе. Однако, есть разница в
именах этих функций. Некоторые системы дают этим функциям имена index
и rindex, другие используют имена strchr и strrchr. Некоторые системы
поддерживают и ту, и другую пару имен, но ни одна пара не работает на
всех системах.
Вы должны выбрать одну из пар имен и использовать ее во всей
Вашей программе. (Лучше использовать strchr и strrchr). Опишите оба
эти имени как функции, возвращающие char *. На системах, которые не
поддерживают такие имена, определите их как макросы. Например,
следующее можно поместить в начало Вашего файла или в файл заголовка,
если Вы хотите использовать strchr и strrchr во всем остальном тексте:
Мы считаем, что HAVE_STRCHR и HAVE_STRRCHR - это макросы,
определенные в системах, в которых соответствующие функции существуют.
Один из способов правильно определить их состоит в использовании
пакета Autoconf.