При разработке переносимых программ лучше исходить из того, что регистр символов, входящих в идентификатор с внешней связью, не имеет значения (т.е. не различаются заглавные и прописные буквы).
Символы входного алфавита, кроме явно определенных в стандарте.
Это касается, в основном, символов, используемых в символьных и строковых константах (например, русские буквы).
Символы из набора времени выполнения (за исключением пустого символа и (в окружении выполнения) явно определенных символов входного символьного набора) и их коды.
В переносимых программах нежелательно использование информации о кодах символов, поскольку они могут различаться в разных реализациях.
Соответствие символов входного алфавита (в символьных и строковых константах) символам алфавита времени выполнения.
В основном это касается управляющих символов. Например, символ "конец строки" (\n) в разных реализациях может быть представлен в потоках ввода-вывода различными последовательностями кодов. Надо стараться писать программу так, чтобы ее поведение не зависело от конкретного представления управляющих символов в окружении выполнения.
Число и порядок символов в целом.
Эти различия несущественны в самостоятельных программах, которые не позволяют себе играть типами (например, преобразуя указатель на целое в указатель на символы и проверяя содержимое памяти по указателю), но могут проявиться при обработке данных, поступающих извне.
Число и порядок следования разрядов в символах из набора символов времени выполнения.
Значение символьной константы, состоящей из символа или управляющей последовательности, не представимой в алфавите времени выполнения.
Переносимой программе не следует использовать информацию этих двух пунктов.
Значение символьной константы, состоящей более, чем из одного символа.
В переносимой программе не следует использовать символьные константы более, чем из одного символа.
Следует ли трактовать "простые" символьные объекты как знаковые или беззнаковые.
Переносимая программа не должна зависеть от того, является ли тип char знаковым или беззнаковым.
Представление и наборы значений различных целочисленных типов.
В переносимой программе лучше всего исходить из минимальных наборов значений, зафиксированных стандартом, а также из той минимальной информации о представлении, которая в приводится в стандарте.
Результат преобразования целого к более короткому знаковому целому или результат преобразования беззнакового целого к знаковому целому той же длины, если значение не может быть представлено.
Переносимая программа не использует эту информацию.
Результаты поразрядных операций над знаковыми целыми.
В переносимой программе следует использовать только такие поразрядные операции, результат которых не зависит от реализации.
Знак остатка целочисленного деления.
Переносимая программа не использует эту информацию.
Является ли сдвиг вправо значения знакового целочисленного типа логическим или арифметическим.
Переносимая программа не должна зависеть от вида сдвига вправо знаковых целых.
Представление и наборы значений различных типов вещественных чисел.
Переносимая программа не зависит от представления вещественных чисел. Наборы значений вещественных типов влияют на точность вычислений.
Способ округления, когда вещественное число преобразуется к более узкому вещественному числу.
В переносимой программе лучше всего исходить из того, что способ округления неизвестен.
Тип целого, которое может вместить максимальный размер массива, то есть тип size_t - тип результата операции sizeof.
Результат преобразования указателя в целое и наоборот.
Тип целого, которое может вместить разность между двумя указателями на один и тот же массив - ptrdiff_t.
Переносимая программа не должна использовать информацию предыдущих трех пунктов.
Элемент смеси union используется как элемент другого типа.
Переносимая программа не должна осуществлять доступ к элементу смеси после того, как был изменен элемент смеси другого типа, поскольку в этом случае используется информация о битовой структуре представления значения соответствующего типа.
Дополнение пустот и выравнивание элементов записей.
Это обычно не доставляет проблем, если только двоичные данные, записанные одной реализацией, не читаются другой. Конечно же, не следует использовать эту информацию в переносимой программе.
Считается ли "простое" целое битовое поле знаковым или беззнаковым.
Переходит ли битовое поле, не умещающееся в одном целом, в следующее.
Порядок расположения битовых полей в целом.
Может ли битовое поле пересекать физические границы ячеек памяти.
Переносимая программа не должна использовать всю эту информацию.
Максимальное число описателей, которые могут модифицировать базовый тип.
Переносимой программе нужно исходить из того, что любая реализация должна допускать использование в модификации базового типа, либо непосредственно, либо через эквивалентность типов, по крайней мере 12 описателей указателей, массивов и функций (в любых комбинациях).
Максимальное число вариантов в переключателе.
Переносимая программа должна исходить из того, что число вариантов в переключателе не должно превышать 255.
Будет ли значение односимвольной символьной константы в выражении, управляющем условным включением фрагментов программ, совпадать со значением такой же константы в наборе символов окружения выполнения. Может ли такая константа иметь отрицательное значение.
Метод связи с входными файлами, подлежащими включению в программу.
Обработка имен в кавычках, относящихся к включаемым файлам.
Поведение каждой директивы #pragma.
Определение имен __DATE__ и __TIME__, когда, соответственно дата и время трансляции не может быть доступно.
Константа, получающаяся при подстановке макроопределения NULL, обозначающая пустой указатель.
Предыдущие 6 пунктов описывают зависящее от реализации поведение препроцессора. Остальные пункты описывают определяемое реализацией поведение библиотечных программ.
Диагностическое сообщение и способ завершения программы, применяемый в функции assert.
Наборы символов, проверяемые в функциях isalnum, isalpha, iscntrl, islower, isprint и isupper.
Значения, выдаваемые математическими функциями при возникновении ошибок области определения.
Устанавливают ли математические функции целое выражение errno в положение ERANGE при возникновении потери значимости.
Набор сигналов для функции signal.
Семантика каждого сигнала, распознаваемого библиотечной функцией signal.
Обработка умолчаний и входов в программу для каждого вида сигналов, распознаваемых функцией signal.
Восстанавливается ли стандартная обработка, если при обработке сигнала функцией, указанной при вызове функции signal, возникает сигнал SIGILL.
Нужно ли заканчивать последнюю строку текстового потока символом "конец строки".
Появятся ли при вводе обычные пробелы, записанные в текстовый поток непосредственно перед символом конца строки текста.
Количество символов NULL, которые дописываются к двоичному потоку.
Характеристики буферизации файлов.
Существует ли файл нулевой длины.
Правила образования правильных имен файлов.
Может ли один файл открываться много раз.
Результат выполнения функции remove над открытым файлом.
Эффект работы функции rename, если файл с новым именем существовал ранее.
Выходная строка, получающаяся при работе преобразования %p в функции fprintf.
Входная строка, поступающая для преобразования %p в функции fscanf.
Интерпретация символа ^, который есть ни первый, ни последний символ в списке сканирования в преобразовании %[ в функции fscanf.
Значение, которое получает errno от функций fgetpos и ftell в случае неудачи.
Сообщения, выдаваемые функцией perror.
Поведение функций calloc, malloc и realloc в случае, если размер запрошенной памяти равен нулю.
Поведение функции abort по отношению к открытым и временным файлам.
Статус, возвращаемый функцией exit, если значение фактического параметра не равно нулю, или значениям макроимен EXIT_SUCCESS и EXIT_FAILURE.
Набор имен окружения и метод изменения списка окружения, используемый функцией getenv.
Содержание и режим выполнения командной строки функцией system.
Знак значения, возвращаемого функцией сравнения (memcmp, strcmp или strncmp), если первая пара различающихся символов разнится в старшем разряде.
Содержание строк сообщений об ошибках, возвращаемых функцией strerror.
Местный временной пояс и летнее время.
Точка отсчета для функции clock.
Метрические ограничения переносимой программы
Переносимая программа должна удовлетворять следующим метрическим ограничениям:
Специфичным видом мобильности приложений на уровне исходных текстов является возможность их выполнения с несколькими версиями одного и того же варианта ОС UNIX, включая ранние версии, далекие от современных стандартов. Достаточно часто поздние версии не обеспечивают полной совместимости с более ранними версиями, поскольку такая совместимость не дала бы возможности добиться в поздних версиях соответствия стандартам.