Кажется, что существует два ортогональных понятия "переносимости":
Мой код компилируется везде из коробки.Его общее поведение одинаково на всех платформах, но детали доступных функций различаются в зависимости от характеристик платформы.
Мой код содержит папку для вещей, зависящих от архитектуры.Я гарантирую, что MYINT32 всегда 32-битный, несмотря ни на что.Я успешно перенес понятие 32 бита на девятипалые пушистые светлячки Марса.
При первом подходе мы пишем unsigned int n;
и printf("%u", n)
, и мы знаем, что кодвсегда работает, но детали, такие как числовой диапазон unsigned int
, зависят от платформы и не имеют значения.( Wchar_t также входит сюда.) Это то, что я бы назвал действительно переносимым стилем.
Во втором подходе мы печатаем все определения и используем такие типы, как uint32_t
.Форматированный вывод с printf
вызывает тонны предупреждений, и мы должны прибегнуть к таким монстрам, как PRI32
.При таком подходе мы получаем странное чувство силы и контроля, зная, что наше целое число всегда имеет ширину 32 бита, но я не решаюсь назвать это «переносимым» - оно просто упрямое.
Фундаментальная концепция, которая требуетконкретное представление - сериализация : документ, который вы пишете на одной платформе, должен быть доступен для чтения на всех других платформах.Сериализация, естественно, когда мы отказываемся от системы типов, должны беспокоиться о порядке байтов и должны принимать решение о фиксированном представлении (включая такие вещи, как кодирование текста).
Результат таков:
- Напишите ядро своей основной программы в переносимом стиле, используя стандартные языковые примитивы.
- Пишите четко определенные, чистые интерфейсы ввода / вывода для сериализации.
Если вы будете придерживаться этого, вам никогда не следуетдаже нужно подумать о том, является ли ваша платформа 32- или 64-разрядной, с прямым или прямым порядком байтов, Mac или ПК, Windows или Linux.Придерживайтесь стандарта, и стандарт будет придерживаться вас.