Warum gibt string::compare
ein int
statt eines kleineren Typs wie short
oder zurück ?char
? Nach meinem Verständnis gibt diese Methode nur -1, 0 oder 1 zurück.
Zweiter Teil, wenn ich eine Vergleichsmethode entwerfen wollte, die zwei Objekte vom Typ vergleicht Foo
und nur -1, 0 oder 1 zurückgeben möchte, wäre die Verwendung short
oder im char
Allgemeinen eine gute Idee?
BEARBEITEN: Ich wurde korrigiert, string::compare
gibt nicht -1, 0 oder 1 zurück, sondern gibt einen Wert> 0, <0 oder 0 zurück. Danke, dass Sie mich auf dem Laufenden gehalten haben.
Die Antwort scheint grob zu sein. Es gibt keinen Grund, einen Typ zurückzugeben, der kleiner als ist int
weil Rückgabewerte "rvalues" sind und diese "rvalues" nicht davon profitieren, kleiner als type int (4 Bytes) zu sein. Viele Leute wiesen auch darauf hin, dass die Register der meisten Systeme wahrscheinlich von Größe sein werdenint
sowieso die werden, da diese Register gefüllt werden, unabhängig davon, ob Sie ihnen einen Wert von 1, 2 oder 4 Byte geben. Es gibt keinen wirklichen Vorteil, a zurückzugeben kleinerer Wert.
BEARBEITEN 2: Tatsächlich sieht es so aus, als ob bei Verwendung kleinerer Datentypen wie Ausrichtung, Maskierung usw. ein zusätzlicher Verarbeitungsaufwand anfällt. Der allgemeine Konsens ist, dass die kleineren Datentypen vorhanden sind, um Speicherplatz zu sparen, wenn mit vielen Daten gearbeitet wird, wie im Fall eines Arrays.
Habe heute etwas gelernt, nochmals vielen Dank Jungs!
string::compare()
Sie verlinken, gibt eindeutig an, dass der Rückgabewert <0, 0 und> 0 -not- -1, 0 und 1 ist.short
oderchar
anstelle vonint
? Die meisten Architekturen speichern den Rückgabewert einer Funktion in einem Register, und ein Wertint
passt genauso gut in ein Register wie einshort
oderchar
. Die Verwendungchar
für numerische Typen ist immer eine schlechte Idee, insbesondere wenn Sie sicherstellen müssen, dass signierte Werte korrekt behandelt werden.char
wäre eine schlechte Idee, da die Codeprüfung für den Rückgabewert, wenn er kleiner als Null ist, auf Plattformenchar
ohne Vorzeichen fehlschlägt .Antworten:
Erstens lautet die Spezifikation, dass ein Wert zurückgegeben wird, der kleiner, gleich oder größer als
0
, nicht unbedingt-1
oder ist1
. Zweitens sind Rückgabewerte r-Werte, die einer integralen Heraufstufung unterliegen. Es macht also keinen Sinn, etwas Kleineres zurückzugeben.In C ++ (wie in C) ist jeder Ausdruck entweder ein r-Wert oder ein l-Wert. Historisch gesehen beziehen sich die Begriffe auf die Tatsache, dass l-Werte links von einer Zuweisung angezeigt werden, während r-Werte nur rechts angezeigt werden können. Heutzutage ist eine einfache Annäherung für Nicht-Klassentypen, dass ein l-Wert eine Adresse im Speicher hat, ein r-Wert nicht. Daher können Sie die Adresse eines r-Werts nicht annehmen, und cv-Qualifizierer (die Bedingung "Zugriff") gelten nicht. In C ++ ist ein r-Wert ohne Klassentyp ein reiner Wert, kein Objekt. Der Rückgabewert einer Funktion ist ein r-Wert, sofern er keinen Referenztyp hat. (Nicht-Klassentypen, die in ein Register passen, werden beispielsweise fast immer in einem Register und nicht im Speicher zurückgegeben.)
Für Klassentypen sind die Ausgaben ein wenig komplexer, aufgrund der Tatsache , dass Sie können Mitgliederfunktionen auf rvalue nennen. Dies bedeutet, dass r-Werte tatsächlich Adressen für den
this
Zeiger haben müssen und cv-qualifiziert sein können, da die cv-Qualifikation eine Rolle bei der Überlastungsauflösung spielt. Schließlich führt C ++ 11 einige neue Unterscheidungen ein, um rvalue-Referenzen zu unterstützen. Auch diese gelten hauptsächlich für Klassentypen.Integrale Förderung bezieht sich auf die Tatsache, dass Integraltypen, die kleiner als a
int
sind, in den meisten Kontexten als Werte in einem Ausdruck verwendet werden, zu denen sie befördert werdenint
. Also selbst wenn ich eine Variable deklariertshort a, b;
, im Ausdrucka + b
, die beidea
undb
werden gefördert ,int
bevor die Zugabe auftritt. In ähnlicher Weise wird, wenn ich schreibea < 0
, der Vergleich mit dem Wert von durchgeführta
, der in einen konvertiert wirdint
. In der Praxis gibt es nur sehr wenige Fälle, in denen dies einen Unterschied macht, zumindest bei 2-Komplement-Maschinen, bei denen ganzzahlige arithmetische Wraps vorhanden sind (dh heute alle bis auf wenige Exoten - ich denke, die Unisys-Mainframes sind die einzigen verbleibenden Ausnahmen). Trotzdem auch auf den gängigsten Maschinen:sollte unterschiedliche Ergebnisse liefern: das erste ist das Äquivalent von
sizeof( short )
, das zweitesizeof( int )
(wegen integraler Förderung).Diese beiden Probleme sind formal orthogonal. rWerte und lWerte haben nichts mit integraler Förderung zu tun. Außer ... integrale Werbung gilt nur für r-Werte, und die meisten (aber nicht alle) Fälle, in denen Sie einen r-Wert verwenden würden, führen zu integraler Werbung. Aus diesem Grund gibt es wirklich keinen Grund, einen numerischen Wert in etwas kleinerem als zurückzugeben
int
. Es gibt sogar einen sehr guten Grund, es nicht als Zeichentyp zurückzugeben. Überladene Operatoren<<
verhalten sich beispielsweise für Zeichentypen häufig anders, sodass Sie nur Zeichen als Zeichentypen zurückgeben möchten. (Sie könnten den Unterschied vergleichen:Der Unterschied besteht darin, dass im zweiten Fall die Hinzufügung dazu geführt hat, dass eine integrale Förderung erfolgt, was zu einer anderen
<<
zu wählenden Überlastung führt .quelle
return values are rvalues, subject to integral promotion
in Ihrer Antwort mehr erklären könnten .signed char
? Würde es sich wie ein signiertes Verhalten verhaltenchar
oder wäre es ein anderer Typ?Es ist beabsichtigt, dass -1, 0 oder 1 nicht zurückgegeben werden.
Es erlaubt (beachten Sie, dass dies nicht für Zeichenfolgen gilt, sondern auch für Zeichenfolgen)
Das ist viel weniger umständlich als:
Das ist, was Sie tun müssten [oder etwas in dieser Richtung], wenn Sie -1, 0 oder 1 zurückgeben müssten.
Und es funktioniert auch für komplexere Typen:
Im String-Fall können wir dies tun:
quelle
compare
Funktion hat Probleme mit dem Überlauf, die (zum Glück) nicht gleichermaßen zutreffen, wenn sie dauertchar*
undchar
kleiner als istint
. Wenn beispielsweise*a
istMAX_INT
und*b
ist,-1
dann*a - *b
ist UB, aber wenn die Implementierung ihr Verhalten definiert, ist das Ergebnis mit ziemlicher Sicherheit negativ.length()
size_t
int
int ist normalerweise (dh auf der meisten modernen Hardware) eine Ganzzahl mit der gleichen Größe wie der Systembus und / oder die CPU-Register, was als Maschinenwort bezeichnet wird. Daher wird int normalerweise schneller weitergegeben als kleinere Typen, da keine Ausrichtung, Maskierung und andere Operationen erforderlich sind.
Die kleineren Typen existieren hauptsächlich, um die Optimierung der RAM-Nutzung für Arrays und Strukturen zu ermöglichen. In den meisten Fällen tauschen sie einige CPU-Zyklen (in Form von Aligment-Operationen) gegen eine bessere RAM-Nutzung.
Wenn Sie Ihren Rückgabewert nicht als signierte oder nicht signierte Centain-Nummer (char, short…) erzwingen müssen, ist es besser, int zu verwenden, weshalb die Standardbibliothek dies tut.
quelle
Es ist ein C-Ismus.
Wenn C
compare
Funktionen vom Typ Typ benötigte , gaben sie immer eine zurückint
. C ++ hat das (leider) gerade übernommen.Die Rückgabe von
int
ist jedoch realistisch gesehen wahrscheinlich der schnellste Weg, da es sich im Allgemeinen um die Größe der Register des verwendeten Systems handelt. (Absichtlich vage.)quelle
short
undchar
kann Leistungseinbußen nach sich ziehen, z. B.255+7
hat ein anderer Wert für achar
undint
so kann eine korrekte Implementierung nicht unbedingt einfach speichern,char
wohin einint
gehen kann, ohne sich um die Übergabe seiner Semantik zu kümmern. Compiler optimieren nicht unbedingt die damit verbundene Ineffizienz.Die Methode gibt keine Ganzzahl in der Menge zurück
{ -1, 0, 1 }
. es kann tatsächlich ein beliebiger ganzzahliger Wert sein.Warum? Der Hauptgrund, an den ich denken kann, ist, dass
int
der Wert der "natürlichen Größe" für die Architektur sein soll; Operationen mit Werten dieser Größe sind normalerweise mindestens genauso schnell (und in vielen Fällen schneller) wie Operationen mit kleineren oder größeren Werten. Dies ist also ein Fall, in dem die Implementierung genügend Spielraum hat, um das zu verwenden, was am schnellsten ist.quelle
Es wäre ok Idee. Ein besserer Weg wäre, einen Bool (wenn Sie nur vergleichen möchten, wenn er gleich ist) oder eine Aufzählung (für weitere Informationen) zurückzugeben:
quelle
Angenommen, einige Leute ändern einen Code von C nach C ++. Sie beschlossen , zu ersetzen ,
strcmp
zustring::compare
.Da
strcmp
kehrtint
, ist es einfacher,string::compare
zurückzukehrenint
, als Geschenk.quelle
Wahrscheinlich, damit es besser funktioniert,
strcmp
das auch diesen Satz von Rückgabewerten hat . Wenn Sie Code portieren möchten, ist es wahrscheinlich intuitiver, Ersetzungen zu haben, die so nah wie möglich sind.Auch ist der Rückgabewert nicht nur
-1
,0
oder1
aber<0
,0
oder>0
.Wie bereits erwähnt, ist es nicht sinnvoll, die Rendite zu verkleinern, da sie einer integralen Werbung unterliegt .
quelle
weil ein boolescher Rückgabewert nur zwei mögliche Werte sein kann (wahr, falsch) und eine Vergleichsfunktion drei mögliche Werte zurückgeben kann (kleiner als, gleich, größer als).
Aktualisieren
Es ist zwar durchaus möglich, einen vorzeichenbehafteten Kurzschluss zurückzugeben, aber wenn Sie wirklich Ihre eigene Vergleichsfunktion implementieren möchten, können Sie einen Nibble- oder Strukturwert mit zwei Booleschen Werten zurückgeben.
quelle
short
undchar
als Alternativen zuint
.