Consider the following:
std::ostream out(nullptr);
Is this legal and well-defined?
How about if I now do:
out << "hello world\n";
Is this legal and well-defined? If so, presumably it's a no-op of sorts?
Yes, it is legal and well-defined to instantiate that stream. You can safely swap it with another stream, or give it a new pointer (this time to an extant buffer) at a later time. The output operation itself is indeed a no-op.
Here's why:
The construction has no non-null precondition, and has only this postcondition:
[C++11: 27.7.3.2/2]:Postcondition:rdbuf() == sb.
Interestingly, it makes an explicit point that no operation shall be performed on sb within the constructor:
[C++11: 27.7.3.2/4]:Remarks: Does not perform any operations onrdbuf().
But note also:
[C++11: 27.7.3.2/1]:Effects: Constructs an object of classbasic_ostream, assigning initial values to the base class by callingbasic_ios<charT,traits>::init(sb)(27.5.5.2).
That init(sb) call has the effect of setting badbit on the stream when sb is NULL:
[C++11: 27.5.5.2/3]:Postconditions: The postconditions of this function are indicated in Table 128.
[C++11: Table 128]:[..]rdstate():goodbitifsbis not a null pointer, otherwisebadbit. [..]
The output operation would result in actions equivalent to dereferencing a null pointer:
[C++11: 27.7.3.1/2]:Two groups of member function signatures share common properties: the formatted output functions (or inserters) and the unformatted output functions. Both groups of output functions generate (or insert) output characters by actions equivalent to callingrdbuf()->sputc(int_type). They may use other public members ofbasic_ostreamexcept that they shall not invoke any virtual members ofrdbuf()exceptoverflow(),xsputn(), andsync().
except it never gets this far, because for basic_ostream::sentry construction:
[C++11: 27.7.3.4/3]:If, after any preparation is completed,os.good()istrue,ok_ == trueotherwise,ok_ == false.
and, for explicit operator basic_ostream::sentry::bool() const;:
[C++11: 27.7.3.4/5]:Effects: Returnsok_.
and:
[C++11: 27.7.3.7/1]:Each unformatted output function begins execution by constructing an object of classsentry. If this object returnstrue, while converting to a value of typebool, the function endeavors to generate the requested output. [..]
…the implication being that no output operation takes place at all when badbit is already set.
This was also the case in C++03.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With