Будируется ли std:: cout?
Просто прочитав старую, но интересную статью "Скотт Майерс"
http://aristeia.com/Papers/C++ReportColumns/novdec95.pdf
В основном речь идет о предпочтении использовать '\n'
над std::endl
(с которым я согласен и использовал одно и то же увеличение в течение многих лет).
НО последний раздел указывает, что это не было включено в его книгу, потому что все это было вызвано спорным из-за двух точек:
-
std::cout
не был буферизирован.
- Состояние
ios::unitbuf
на std:: cout явно не определено (зависит от реализации).
Я быстро просмотрел, но не смог найти явную ссылку на стандарт для 1
. Является ли std::cout
небуферизованным вопреки тому, что я всегда понимал?
Ответы
Ответ 1
Да, он забуферирован:
С++ 11 27.4.2 [узкие. потоки.объектов]/3: Объект cout
управляет выводом в буфер потока, связанный с объектом stdout
В статье упоминается проект версии 1995 года, который стал стандартом С++ 98. Я не знаю, могло ли это сказать что-то другое.
Как и для точки 2, unitbuf
изначально ложно во всех потоках (заданных пост-условиями конструктора basic_ios
), за исключением cerr
и wcerr
, которые явно указывают иначе. Опять же, это может быть различным в упоминании древнего проекта.
Ответ 2
Во-первых, нет требования, чтобы std::cout
(или даже std::cerr
)
небуферизован. Единственное требование состоит в том, чтобы std::cerr
имели
std::basic_ios::unitbuf
set (чтобы он смылся в конце каждого
выходная функция: <<
или неформатная функция вывода). С другой
если вы не вызвали std::basic_ios::sync_with_stdio(false)
,
вывода в потоки С++ и вывода на соответствующий
C-потоки (т.е. std::cout
и stdout
) должны иметь одинаковые эффекты.
Теоретически это можно сделать несколькими способами: stdout
функции могут
вперед к выводам std::cout
, std::cout
вывод может пересылаться на
stdout
, или они могут совместно использовать некоторую общую реализацию буфера в соответствии с
капот. На практике практически все реализации имеют std::cout
пересылка на stdout
.
C указывает, что stderr
не полностью буферизирован и что stdout
может
быть полностью буферизованным только в том случае, если можно определить, что оно не относится к
интерактивное устройство (для некоторой реализации определено значение
"интерактивное устройство" ). Как правило, stdout
будет буферизироваться по строке (a
концепция, которая не существует в iostream), и stderr
будет
небуферизованный, но не гарантированный стандартом C (и может не быть
правда сегодня, в последний раз, когда я действительно смотрел, прошло более двадцати лет
тому назад). Во всяком случае, реализация, которая просто переходит на stdout
, будет
следовать правилам реализации С, которые он пересылает, и
doesnt 'все еще должен предпринять некоторые шаги, чтобы гарантировать, что вывод к
std::cout
и stdout
выходит в правильном порядке и что stdout
ведет себя "как бы", он подчиняется правилам C.
Если вы беспокоитесь о производительности, вам может понадобиться запустить некоторые
испытания. Попробуйте измерить время, необходимое для вывода на std::ofstream
вы открыли себя по сравнению с временем, которое требуется для вывода на
std::cout
(оба с и без вызова sync_with_stdio
),
с перенаправлением вывода. Различия должны быть интересными.
Ответ 3
Стандарт С++ определяет все входные и выходные данные как "как будто", все чтение и запись в конечном итоге происходят с помощью чтения и записи потоков C ([iostream.objects.overview]):
Заголовок объявляет объекты, которые связывают объекты со стандартными потоками C, предусмотренными функциями, объявленными в (27.9.2), и включает в себя все заголовки, необходимые для использования этих объектов.
Для поведения стандартных потоков C, прикрепленных к этим объектам, мы должны обратиться к стандарту C (§7.19.3):
При запуске программы три текстовых потока предопределены и их явно не нужно открывать - стандартный вход (для чтения обычного входа), стандартный выход (для записи традиционный выход) и стандартная ошибка (для записи диагностического вывода). Как первоначально открыт, стандартный поток ошибок не полностью буферизирован; стандартный ввод и стандартный выходные потоки полностью буферизуются тогда и только тогда, когда поток можно определить, чтобы не ссылаться к интерактивному устройству.
Здесь я цитирую из стандарта C99, но я уверен, что (по модулю изменения нумерации разделов) то же самое во всех версиях стандарта C.
Ответ 4
Из того, что я читал в форме здесь, cout обычно буферизуется, но когда он обнаруживает, что он печатает в интерактивной среде, например в консоли, он возвращается к небуферизованным.
Итак, если вы перенаправляете вывод (используя " > " в UNIX), то буферизованное поведение срабатывает.
Подробнее в связанном сообщении.
Ответ 5
В соответствии с этой страницей - http://www.programmingincpp.com/flush-the-output-stream-buffer.html - std:: cout буферизуется. У меня было что-то не распечатывать, потому что сбой программы произошел после того, как cout <..., но до того, как он был сброшен:
cout << "My error or flag message, but it not flushed, so I never see it";
//system crash!
cout << endl;