Рассмотрим следующее:
std::ostream out(nullptr);
Является ли это законным и четко определенным?
А если я сейчас сделаю:
out << "hello world\n";
Является ли это законным и четко определенным? Если да, то, по-видимому, это не-op рода?
Рассмотрим следующее:
std::ostream out(nullptr);
Является ли это законным и четко определенным?
А если я сейчас сделаю:
out << "hello world\n";
Является ли это законным и четко определенным? Если да, то, по-видимому, это не-op рода?
Да, это законно и четко определено для создания экземпляра этого потока. Вы можете безопасно обменять его другим потоком или дать ему новый указатель (на этот раз для существующего буфера) в более позднее время. Сама операция вывода действительно не работает.
Вот почему:
Конструкция не имеет ненулевого предварительного условия и имеет только это постусловие:
[C++11: 27.7.3.2/2]:Постусловие:rdbuf() == sb.
Интересно, что он явно указывает, что в sb внутри конструктора не должно выполняться никаких операций:
[C++11: 27.7.3.2/4]:Примечания: Не выполняет никаких операций сrdbuf().
Но обратите внимание также:
[C++11: 27.7.3.2/1]:Эффекты: Создает объект классаbasic_ostream, назначая начальные значения базовому классу, вызываяbasic_ios<charT,traits>::init(sb)(27.5.5.2).
Этот вызов init(sb) влияет на установку badbit в потоке, когда sb имеет значение NULL:
[C++11: 27.5.5.2/3]:Постусловия: постусловия этой функции указаны в таблице 128.
[C++11: Table 128]:[..]rdstate():goodbitеслиsbне является нулевым указателем, в противном случаеbadbit. [..]
Операция вывода приведет к действиям, эквивалентным разыменованию нулевого указателя:
[C++11: 27.7.3.1/2]:Две группы сигнатур функций-членов имеют общие свойства: форматированные выходные функции (или вставки) и неформатированные выходные функции. Обе группы выходных функций генерируют (или вставляют) выходные символы посредством действий, эквивалентных вызовуrdbuf()->sputc(int_type). Они могут использовать другие публичные членыbasic_ostream, за исключением того, что они не должны вызывать никаких виртуальных членовrdbuf()кромеoverflow(),xsputn()иsync().
за исключением того, что он никогда не заходит так далеко, потому что для basic_ostream::sentry построения:
[C++11: 27.7.3.4/3]:Если после завершения любой подготовкиos.good()true,ok_ == trueв противном случаеok_ == false.
а для explicit operator basic_ostream::sentry::bool() const;:
[C++11: 27.7.3.4/5]:Эффекты: возвращаетok_.
и
[C++11: 27.7.3.7/1]:Каждая неформатированная выходная функция начинает выполнение, создавая объект классаsentry. Если этот объект возвращаетtrue, при преобразовании в значение типаbool, функция пытается сгенерировать запрошенный выход. [..]
& hellip; подразумевается, что никакой выходной операции вообще не происходит, когда badbit уже установлен.