Мне было интересно, действительно ли IO-потоки переносимы (я думаю, что они должны быть, но я хочу быть уверен)? особенно при обработке файлов, используемых как в Unix, так и в Windows.
В частности, если я дам двойное значение в файл в Windows, а затем прочитать то же значение
на Unix из файла с помощью iostreams, это не вызовет проблем из-за вариации
в порядке байтов двух операционных систем?
как насчет отформатированного io? Я где-то читал, не уверенный, где, что когда дело доходит до манипулирования отформатированными данными, есть некоторая разница в том, как windows и unix обрабатывают то же самое. Может кто-нибудь, пожалуйста, пролить свет на этот вопрос?
Стандарт C ++ является абстрактным и не затрагивает какую-либо конкретную ОС (AFAIK). Итак, библиотека iostream является переносимой. Сказав это, стандарт C ++ допускает, чтобы определенные детали реализации, включая некоторые видимые пользователю (а не просто скрытые в стандартной библиотеке C ++), зависели от реализации. Это позволяет провайдеру ОС и / или компилятору выбирать предпочтительный способ реализации стандарта C ++.
Любой код, который опирается на поведение, зависящее от реализации, очевидно, не является переносимым, даже в разных версиях одной и той же ОС и / или компилятора. Другими словами, такого кода следует избегать.
Примечание: иногда необходимо написать код, зависящий от реализации. В этом случае важно защитить код от нарушения предполагаемого поведения, зависящего от реализации. Например, программа может предполагать, что sizeof(long unsigned)==8
, В этом случае, по крайней мере, static_assert(sizeof(long unsigned)==8,"long unsigned not 8 bytes")
должен остановить компиляцию неверного кода, но в идеале должна существовать альтернативная версия, которая должна быть выбрана с помощью шаблона (или макросов в стиле C). Стандарт C ++ 11 фактически обеспечивает тип std::uint64_t
с гарантированный sizeof(std::uint64_t)==8
(и аналогичные), чтобы избежать таких проблем. Тем не мение, sizeof(ostream)
остается зависимым от реализации.
Он переносим в том смысле, что если вы записываете определенную последовательность байтов из одной системы, переносите эту последовательность в другую систему (по файлу или по сокету, это не имеет значения), вы можете прочитать ту же последовательность байтов на Другая сторона. Если вы пишете или читаете в текстовом режиме, а не в двоичном режиме, то окончания строк (и я думаю, что в теории другие специальные символы, определяемые реализацией) могут быть интерпретированы повторно.
Какие не портативный это точное представление double
как последовательность байтов, либо двоичная или же отформатирована. Двоичный из-за, например, endian-ness, и отформатированный из-за тонких различий в библиотеках времени выполнения, которые могут означать, что ваши результаты могут отличаться (или иногда больше) от улипания при кодировании в строку одной системой и обратно в double
другим, даже если вы выводите то, что должно быть достаточно десятичных цифр точности. Строковое представление значений NaN также оставлено для реализации.
Что касается стандарта C ++, double
не обязательно должен быть значением двойной точности IEEE. Таким образом, теоретически не может быть ничего общего между двоичными представлениями, а также большими различиями в отношении того, какие значения могут быть представлены и, следовательно, какие строки выводятся / принимаются при выполнении форматированного ввода-вывода. На практике IEEE обычно используется, и строки обычно не вносят больше ошибок, чем вы ожидаете в операциях с плавающей запятой.
Файл ввода вывода: Да, они совместимы. Поток битов в Unix такой же, как поток битов в Windows. Двойное значение в Unix такое же, как в Windows, так как оба следуют стандарты.
Форматирование: я не знаю ни о каком двоичном форматировании (в примере double), и вы можете говорить о тексте. Форматирование текста в Windows отличается от Unix, и это является причиной многих проблем.
Переносимость двоичного интерфейса / кода: если вы используете функции для ввода-вывода, он не является переносимым. std :: input / output streams, то есть реализация f / o / stream не является переносимой, и при этом она не была разработана, чтобы быть переносимой.