cstdio streams iostream vs-streams?
Habe ich gerade gelernt, von der Existenz der ios_base::sync_with_stdio
- Funktion, die im Grunde können Sie ausschalten (oder wenn Sie bereits ausgeschaltet wurde) die Synchronisierung zwischen iostream
- streams in C++ und die cstdio
- streams, die Teil des Standard-C.
Nun, ich dachte immer, dass stdout
, stderr
und stdin
in C waren im wesentlichen eingewickelt in einen Satz von Objekten in C++ in der iostreams-Klassen. Aber wenn Sie haben, werden synchronisiert mit jedem anderen, dies würde bedeuten, dass C++'s iostream
Klassen sind nicht ein wrapper um die C stdin
etc.
Ich bin ganz verwirrt von diesem? Kann jemand klären, wie C++iostream-und C stdio sind verschiedenen Dinge, die genau das tun die gleiche Sache, nur auf einer anderen Ebene der Abstraktion? Ich dachte, Sie waren die gleiche!?
Wie es ist, dass Sie synchronisiert werden? Ich dachte immer, Sie waren die gleiche Sache, eine Verpackung der anderen, im wesentlichen.
- +1, woah ich dachte immer, die C++
iostream
wurde ein wrapper der Cstdio
zu.
Du musst angemeldet sein, um einen Kommentar abzugeben.
C-und C++ - standards stellen keine Anforderungen auf, wie die Dinge umgesetzt werden, gerade was die Wirkung von bestimmten Operationen ist. Für die
<stdio>
vs.<iostream>
Funktionalität bedeutet dies, dass man wickeln konnte, die andere, beide konnten im wesentlichen die gleichen, oder dass Sie sind entweder völlig unabhängig. Technisch, mit einer gemeinsamen Umsetzung wäre ideal für mehrere Gründe (z.B. gäbe es keine Notwendigkeit für explizite Synchronisierung und würde es einen definierten Mechanismus zu erweiternFILE*
für Benutzer-definierte Systeme), aber ich bin mir nicht bewusst, von jedem system, das wirklich macht. Mit einer Implementierung werden eine Hülle für den anderen möglich ist und die Umsetzung<iostream>
s in Bezug auf<stdio>
war eine typische Implementierung Wahl Sie hat zwar den Nachteil, dass es stellt eine zusätzliche Kosten für bestimmte Operationen und die meisten C++ - standard-Bibliotheken wurden auf die Verwendung völlig getrennte Implementierungen.Leider beide gewickelt und die selbständige Umsetzung ein gemeinsames problem: I/O ist schrecklich ineffizient, wenn ein Charakter level. Also, im Grunde ist es zwingend erforderlich, um buffer-Zeichen und Lesen aus oder schreiben in einen Puffer. Dies funktioniert gut für Strömungen, die voneinander unabhängig sind. Die fangen die standard-C-streams
stdin
,stdout
,stderr
und Ihre C++ - schmale Figur-Pendantsstd::cin
,std::cout
,std::cerr
/std::clog
- und C++ - wide-character Gegenstückestd::wcin
,std::wcout
,std::wcerr
/std::wclog
bzw.: was passiert, wenn ein Nutzer liest sowohl ausstdin
undstd::cin
? Wenn entweder von diesen stream Lesen, einen Puffer von Zeichen aus dem zugrunde liegenden OS-stream der liest würde außerhalb der Reihenfolge angezeigt werden. Ebenso, wenn beidestdout
undstd::cout
verwendet unabhängigen Puffer-Zeichen erscheinen würde, um unerwartete, wenn ein Benutzer schreibt sowohl auf beiden streams. Als ein Ergebnis, gibt es spezielle Regeln, die auf die standard-C++ - stream-Objekte (d.h.std::cin
,std::cout
,std::cerr
, undstd::clog
und Ihre wide-character Gegenstücke), die Mandat, dass Sie eine Synchronisierung mit Ihren jeweiligen<stdio>
Gegenstück. Effektiv, dies bedeutet, dass speziell diese C++ - Objekte verwenden Sie entweder eine gemeinsame Umsetzung direkt oder, dass Sie umgesetzt werden in Bezug auf<stdio>
und nicht buffer-Zeichen.Es wurde erkannt, dass die Kosten für diese Synchronisation ist ganz wesentlich, wenn die Implementierungen nicht teilen, eine gemeinsame Basis und kann unnötig sein, für einige Benutzer: wenn ein Benutzer verwendet nur
<iostream>
er will nicht zahlen für die zusätzliche Dereferenzierung und, noch wichtiger, er will nicht bezahlen für die extra Kosten, die nicht mit einem Puffer. Für die sorgfältige Implementierung werden die Kosten nicht mit einem Puffer durchaus erheblich sein kann, weil es bedeutet, dass bestimmte Vorgänge am Ende mit zu tun, eine überprüfung und ggf. eine virtuelle Funktion Aufruf in jedem Schleifendurchlauf, anstatt nur einmal in eine Weile. Sostd::sync_with_stdio()
können verwendet werden, um diese Synchronisierung ausschaltet, was bedeutet, dass die standard-stream-Objekte ändern Ihre interne Implementierung mehr oder weniger vollständig. Da die stream-Puffer der standard-stream-Objekte können ersetzt werden, durch einen Nutzer, leider ist die stream-Puffer kann nicht ersetzt werden, aber die interne Implementierung der stream-Puffer können verändert werden.In guten Implementierungen der
<iostream>
Bibliothek alle dies betrifft aber nur die standard-stream-Objekte. Das heißt, Datei-streams werden sollte, völlig unberührt. Allerdings, wenn Sie möchten, verwenden Sie die standard-stream-Objekte und wollen eine gute Leistung erzielen, die Sie eindeutig nicht wollen, zu mischen<stdio>
und<iostream>
und Sie wollen, schalten Sie die Synchronisierung aus. Vor allem, wenn man I/O-performance zwischen<stdio>
und<iostream>
Sie sollten sich dessen bewusst sein.Eigentlich die
stdout
,stderr
undstdin
sind die Datei-Handler des OS. UndFILE
Struktur von C als auchiostream
- Klassen von C++ sind sowohl Wrapper dieser Datei-Handler. Beide iostream-Klassen-und DATEI-Struktur kann Ihre eigenen Puffer oder etwas anderes, das muss synchronisiert werden, zwischen den einzelnen anderen, um sicherzustellen, dass der input aus Datei oder die Ausgabe in die Datei richtig gemacht.stdin
und Freunde sind Strukturen vom TypFILE
und einC
Sache. Der os hat einfach Datei-Deskriptoren0
,1
und2
im Sinneunistd.h
als#define STDIN_FILENO 0
.Okay, hier ist was ich gefunden habe.
Eigentlich die I/O ist letztlich durchgeführt von native Systemaufrufe und-Funktionen.
Nun, nehmen Sie Microsoft Windows zum Beispiel. Es gibt tatsächlich verfügbare Griffe für
STDIN
,STDIO
etc (siehe hier). Also im Grunde, sowohl die C++iostream
- und C -stdio
rufen Sie die native-system-Funktionen, die C++iostream
nicht umbrochen, C-I/O-Funktionen (in modernen Implementierungen). Es ruft die native-system-Methoden direkt.Auch, fand ich dies:
(Quelle)
Daher ruft
sync_with_stdio()
tatsächlich Veränderungen der zugrunde liegenden Datei-Deskriptoren. Es war in der Tat Hinzugefügt, die von den Designern zur Sicherstellung der Kompatibilität der älteren C++ - I/O-Systeme wie Windows-32 die verwendeten Griffe statt Integer.Beachten Sie, dass die Verwendung
sync_with_stdio()
ist nicht notwendig, mit modernen C++ - template-basierte STL I/O.Einer kann ein wrapper um die anderen (und das funktioniert in beide Richtungen. Sie könnte implementieren
stdio
Funktionen durch die Verwendungiostream
- und Umgekehrt. Oder Sie können schreiben Sie Sie völlig unabhängig.Sowie
sync_with_stdio
garantiert, dass die zwei Ströme werden synchronisiert, wenn Sie aktiviert ist. Aber Sie kann immer noch synchronisieren, wenn es deaktiviert auch, wenn Sie das wirklich wollen.Aber auch wenn man selbst einen wrapper um die andere, könnte man immer noch einen Puffer, den der andere nicht teilen, zum Beispiel so, dass die Synchronisierung ist immer noch notwendig.
sync_with_stdio
. Ist es nicht eher ein Kompatibilitätsproblem?FILE
Ebene).Sie sind das gleiche, aber man könnte auch gepuffert werden, separarately. Dies könnte sich auf code, der mischt das verwenden von C-und C++ - I/O, wie diese
Für diese Arbeit, die zugrunde liegenden streams synchronisiert werden muss irgendwie. Auf manchen Systemen ist dieser könnte bedeuten, dass die performance leiden könnte.
So, der standard ermöglicht es, Sie zu nennen
std::sync_with_stdio(false)
zu sagen, dass Sie kümmern sich nicht darum, code wie folgt, aber würde es vorziehen, um die standard-streams arbeiten, so schnell wie möglich ob es einen Unterschied macht. Auf vielen Systemen ist es nicht einen Unterschied machen.