Ja, es ist legal und gut definiert, diesen Stream zu instanziieren. Sie können es sicher mit einem anderen Stream austauschen oder ihm zu einem späteren Zeitpunkt einen neuen Zeiger (dieses Mal auf einen vorhandenen Puffer) geben. Die Ausgabeoperation selbst ist in der Tat ein No-Op.
Hier ist der Grund:
Die Konstruktion keine nicht-null Voraussetzung hat, und hat nur diese Nachbedingung:
[C++11: 27.7.3.2/2]:
Nachbedingung: rdbuf() == sb
.
Interessanterweise macht es einen expliziten Punkt, dass keine Operation wird auf sb
im Konstruktor durchgeführt werden:
[C++11: 27.7.3.2/4]:
Bemerkungen: Führt keine Operationen auf rdbuf()
. auch
Aber Achtung:
[C++11: 27.7.3.2/1]:
Effekte: Konstruiert ein Objekt der Klasse basic_ostream
, Anfangswerte an die Basisklasse Zuweisung durch den Aufruf basic_ios<charT,traits>::init(sb)
(27.5.5.2).
Das init(sb)
Aufruf hat die Wirkung der badbit
auf den Strom eingestellt wird, wenn sb
NULL ist:
[C++11: 27.5.5.2/3]:
Nachbedingungen: Die Nachbedingungen dieser Funktion sind in der Tabelle angegeben 128.
[C++11: Table 128]:
[..]rdstate()
: goodbit
wenn sb
kein Nullzeiger ist, sonst badbit
. [..]
die Ausgabeoperation würde Ergebnis in Handlungen entspricht dereferenzieren einen Nullzeiger:
[C++11: 27.7.3.1/2]:
Zwei Gruppen von Mitgliedsfunktionssignaturen teilen gemeinsame Eigenschaften: Die formatierten Ausgabefunktionen (oder Kuvertiermaschinen) und die unformatierten Ausgabefunktionen. Beide Gruppen von Ausgabefunktionen erzeugen (oder fügen) Ausgabezeichen durch Aktionen ein, die dem Aufruf rdbuf()->sputc(int_type)
entsprechen. Sie dürfen andere öffentliche Mitglieder von basic_ostream
verwenden, außer dass sie keine virtuellen Mitglieder von rdbuf()
mit Ausnahme von overflow()
, xsputn()
und sync()
aufrufen dürfen.
außer es nie so weit, denn für basic_ostream::sentry
Bau bekommt:
[C++11: 27.7.3.4/3]:
Wenn nach jeder Vorbereitung abgeschlossen ist, os.good()
true
ist, ok_ == true
sonst ok_ == false
.
und für explicit operator basic_ostream::sentry::bool() const;
:
[C++11: 27.7.3.4/5]:
Effekte: Gibt ok_
.
und:
[C++11: 27.7.3.7/1]:
Jede unformatierte Ausgangsfunktion beginnt die Ausführung durch ein Objekt der Klasse sentry
zu konstruieren. Wenn dieses Objekt true
zurückgibt, versucht die Funktion beim Konvertieren in einen Wert vom Typ bool
die angeforderte Ausgabe zu generieren. [..]
& hellip; die Implikation, dass keine Ausgabeoperation überhaupt stattfindet, wenn badbit
bereits gesetzt ist.
This was also the case in C++03.
ich immer ein Unit-Test hinzufügen, wenn ich so etwas denken sollte funktionieren, und scheint gültig zu sein. Auf diese Weise, wenn jemand für einen anderen Compiler/Plattform stdlib erstellt, dann wissen sie, dass es kaputt ist. – paulm
@paulm: Ich stimme fast zu, außer Unit Tests sind nicht etwas, auf das Sie sich verlassen sollten, um die Definiertheit zu validieren. –
Wenn nicht auf Speicher außerhalb der Grenzen oder etwas zugegriffen wird, sehe ich kein Problem? Aber dann sollten Unit Tests mit App Verifier aktiviert sein/Valgrind usw. – paulm