Подтвердить что ты не робот

Написание переносимой программы на С - что нужно учитывать?

Для проекта в университете мне нужно расширить существующее приложение C, которое в конечном итоге должно быть запущено в самых разных коммерческих и некоммерческих системах Unix (FreeBSD, Solaris, AIX и т.д.).

Какие вещи я должен учитывать, когда хочу написать программу C, которая наиболее переносима?

4b9b3361

Ответ 1

Лучший совет, который я могу дать, - это каждый день переходить на другую платформу, проверяя, как вы идете. Это приведет к тому, что различия в платформе будут торможены, как больной палец, и научат вас проблемам с переносимостью в то же время.

Сохранение тестирования кросс-платформы для конца приведет к сбою.

В стороне

  • Целочисленные размеры могут различаться.
  • числа с плавающей запятой могут быть представлены по-разному.
  • целые числа могут иметь различный эндианство.
  • Параметры компиляции могут отличаться.
  • include имена файлов могут различаться.
  • реализация битовых полей будет различаться.

Как правило, рекомендуется установить уровень предупреждения вашего компилятора как можно выше, чтобы увидеть то, о чем компилятор может жаловаться.

Ответ 2

Раньше я писал утилиты C, которые затем поддерживал бы с 16-битной до 64-битной архитектуры, включая 60-битные машины. Они включали по крайней мере три разновидности "endianness", различные форматы с плавающей запятой, различные кодировки символов и различные операционные системы (хотя преобладал Unix).

  • Оставайтесь как можно ближе к стандарту C. Для функций/библиотек, не являющихся частью стандарта, используйте как можно более широко поддерживаемую базу кода, как вы можете найти. Например, для работы в сети используйте интерфейс сокета BSD с нулевым или минимальным использованием опций сокетов низкого уровня, внеполосной сигнализации и т.д. Чтобы поддерживать большое количество разрозненных платформ с минимальным персоналом, вам придется остановиться с обычными ванильными функциями.
  • Будьте в курсе того, что гарантировано стандартом, и что типичное поведение реализации. Например, указатели не обязательно имеют тот же размер, что и целые числа, а указатели на разные типы данных могут иметь разную длину. Если вы должны сделать предположения, зависящие от реализации, задокументируйте их торологично. Lint, или --strict, или что-то, что ваш набор инструментов разработки имеет в качестве эквивалента, жизненно важно здесь.
  • Заголовочные файлы - ваш друг. Используйте реализованные макрокоманды и константы. Используйте определения заголовков и #ifdef, чтобы помочь изолировать те экземпляры, где вам нужно покрыть небольшое количество альтернатив.
  • Не предполагайте, что на текущей платформе используются символы EBCDIC и упакованные десятичные целые числа. Существует также большое количество ASCII - двух дополнительных машин.: -)

При всем этом, если вы избегаете tempation для написания вещей несколько раз и #ifdef основных частей кода, вы обнаружите, что кодирование и тестирование на разрозненных платформах помогает быстрее находить ошибки. Вы в конечном итоге создадите более дисциплинированные, понятные, поддерживаемые программы.

Ответ 3

  • Использовать по крайней мере два компилятора.
  • У вас есть система непрерывной сборки, которая предпочтительно строится на разных целевых платформах.
  • Если вам не нужно работать на очень низком уровне, попробуйте использовать некоторую библиотеку, которая обеспечивает абстракцию. Маловероятно, что вы не найдете сторонние библиотеки, которые обеспечивают хорошую абстракцию для вещей, которые вам нужны. Например, для сети и связи есть ACE. Boost (например, файловая система) также переносится на несколько платформ. Это библиотеки С++, но могут быть и другие библиотеки C (например, curl).
  • Если вам нужно работать на низком уровне, имейте в виду, что платформы иногда имеют другое поведение даже на таких вещах, как posix, где они должны иметь одинаковое поведение. Вы можете посмотреть исходный код библиотек выше.

Ответ 4

Это очень длинный список. Лучше всего это прочитать примеры. Например, источник perl. Если вы посмотрите на источник perl, вы увидите гигантский процесс создания файла заголовка, который имеет дело с примерно 50 проблемами платформы.

Прочитайте его и плачьте, или займитесь.

Ответ 5

Одна из проблем, которые вам могут потребоваться, чтобы быть в курсе (например, если ваши файлы данных должны работать на разных платформах) endianness.

Номера представлены по-разному на двоичном уровне на разных архитектурах. Системы Big-Endian заказывают наиболее значимые байтовые системы с первым и мало-конечном порядком сначала заказывают младший младший байт.

Если вы пишете некоторые необработанные данные в файл в одном контенте, а затем читаете этот файл обратно в системе с другим контентом, у вас, очевидно, будут проблемы.

Вы должны иметь возможность получить континент во время компиляции в большинстве систем от sys/param.h. Если вам нужно обнаружить его во время выполнения, один метод должен использовать объединение int и a char, а затем установить char в 1 и посмотреть, какое значение имеет int.

Ответ 6

Попробуйте придерживаться ANSI C.

Ответ 7

Список может быть длинным, но это не так много, как поддержка Windows и MSDOS. Что общего со многими утилитами.

Обычный метод состоит в том, чтобы отделить модули основного алгоритма от тех, которые относятся к операционной системе - в основном стратегия многоуровневой абстракции.

Дифференциация между несколькими вкусами unix довольно проста в сравнении. Либо придерживайтесь функций, которые используют одни и те же имена RTL, либо смотрят на соглашение большинства для поддерживаемых платформ и #ifdef в исключениях.

Ответ 8

Постоянно ссылайтесь на стандарты POSIX для любых функций библиотеки, которые вы используете. Части стандарта неоднозначны, а некоторые системы возвращают разные стили кодов ошибок. Это поможет вам проактивно найти тех, кто действительно трудно найти несколько разных ошибок реализации.