Цитата(Spym @ Nov 7 2010, 09:55)

Как я уже писал, на момент входа в main дескрипторы для stdin/stdout/stderr уже существуют, и инициализируются при первом обращении при помощи __sinit.
В случае newlib, вы получите дескриптор _reent->_stdin (ну или _stdout, _stderr) (посмотрите в newlib: sys/reent.h) - это позволит принять решение о целевом устройстве.
Не могу с Вами полностью согласиться.
Стандартные потоки, безусловно, существуют, как некий объект в памяти. Вопрос был в том, можно ли начать работать с этими объектами, предварительно явно их не инициализировав. О том, что они автоматически инициализируются при первом обращении, я не знал, спасибо за информацию. Мысль же моя заключалась в том, что для последующей работы с выводом на низком уровне (в соответствующих системных вызовах) необходимо, чтобы этим системным вызовам передавались осмысленные аргументы и, в частности, файловый дескриптор. При явной инициализации потока (через fopen или fdopen) это осмысленное значение предоставляет программист. А если инициализация происходит "автомагически", без участия программиста, откуда тогда возьмется это осмысленное значение?
Вот сейчас я посмотрел код newlib. Значение дескриптора хранится в поле
_file структуры FILE. То есть системным вызовам, в нашем случае _write(), в качестве первого аргумента передается
_reent->_stdout->_file. Теперь смотрим, какое же значение там находится. __sinit() для инициализации стандартных потоков вызывает __sfp(), которая, в свою очередь, инициализирует поле _file значением -1. Таким образом, при выполнении каких-либо операций с таким потоком системным вызовам будет передаваться -1 в качсетве файлового дескриптора, что традиционно означает невалидный дескриптор, и такой системный вызов, как правило, должен давать ошибку EBADF (bad file descriptor). По крайней мере, никакого решения о целевом устройстве такой дескриптор принять не позволит.
Конечно, если в целевой системе заведомо существует только одно устройство ввода/вывода (например один com-порт), тогда все операции производятся с ним и только с ним, и можно, наверное, в системных вызовах не анализировать значение дескриптора. Но как только мы допускаем наличия нескольких логических устройств (хотя бы двух com-портов), возникает и необходимость мультиплексировать операции ввода/вывода, а для этого потребуется селектор, которым и является дескриптор, передаваемый первым аргументом. И тогда придется-таки открывать потоки явно через fopen(3)/fdopen(3)...