In C ist es legal, etwas zu schreiben wie:
int foo = +4;
Soweit ich das beurteilen kann, ist das unäre Plus (+
) in +4
ist ein no-op. Ist es?
zneak
In C ist es legal, etwas zu schreiben wie:
int foo = +4;
Soweit ich das beurteilen kann, ist das unäre Plus (+
) in +4
ist ein no-op. Ist es?
Sie können es als eine Art Behauptung verwenden, dass ein Ausdruck einen arithmetischen Typ hat:
#define CHECK_ARITHMETIC(x) (+(x))
Dies erzeugt einen Kompilierzeitfehler, wenn x
wertet zu (sagen wir) einem Zeiger aus.
Das ist ungefähr der einzige praktische Nutzen, der mir einfällt.
Sie können auf diese Weise auch einen Aufzählungswert in seinen ganzzahligen Wert umwandeln.
– GManNickG
9. Juli 2011 um 21:14 Uhr
Warum kann man das nicht auch mit z.B. (-(-(x)))
?
– Aaron Yodaiken
10. Juli 2011 um 1:06 Uhr
@luxun @zneak: Interessante Idee … Mal sehen … OK, wie wäre es damit. Wenn int
ist 32-bit und x
ist zufällig ein int
gleicht -2^31
dann -x
wird eine vorzeichenbehaftete Ganzzahl überlaufen, was technisch gesehen ein undefiniertes Verhalten ist. 🙂
– Nemo
10. Juli 2011 um 3:40 Uhr
@zneak: Der Punkt ist, einen Kompilierzeitfehler auszulösen, wenn der Ausdruck einen Zeigertyp hat, aber ein No-Op zu sein, wenn er einen arithmetischen Typ hat. Ihre Version funktioniert gut, mit Ausnahme von arithmetischen Ausdrücken, die zufällig ausgewertet werden INT_MIN
. (Nun, zumindest theoretisch. In der Praxis funktioniert es wahrscheinlich auf jeder realistischen Maschine.) Dennoch sagt eine strenge Lektüre des Standards, dass diese unterschiedlich sind.
– Nemo
10. Juli 2011 um 5:34 Uhr
@zneak: Auch wenn Sie es nicht in einer Aufgabe verwenden, sondern nur zur Bewertung -x
Wenn x
ist INT_MIN
ist technisch gesehen ein undefiniertes Verhalten, glaube ich.
– Nemo
10. Juli 2011 um 6:31 Uhr
Gemäß dem C90-Standard in 6.3.3.3:
Das Ergebnis des unären + Operators ist die Wert seines Operanden. Die ganzzahlige Heraufstufung wird am Operanden durchgeführt. und das Ergebnis hat den beförderten Typ.
und
Der Operand des unären + oder – Operators muss haben arithmetischer Typ..
So +x
ist ein Noop, es sei denn sizeof x < sizeof(int)
?
– zneak
9. Juli 2011 um 19:45 Uhr
Diese Zitate aus dem Standard zeigen, dass das unäre + nicht einfach ein No-Op ist. Es führt eine integrale Heraufstufung des Operanden durch. Und, möglicherweise noch wichtiger, es verwandelt einen lvalue in einen rvalue.
– Sander DeDycker
9. Juli 2011 um 19:48 Uhr
Nun, das ist theoretisch möglich sizeof(short) == sizeof(int)
aber ein short
hat eine Auffüllung, und theoretisch muss auf einem solchen System die Auffüllung auf Null gesetzt oder das Vorzeichen erweitert werden. Theoretisch.
– Dietrich Ep
9. Juli 2011 um 19:49 Uhr
Beachten Sie, dass sich arithmetische Typen sowohl auf integrale Typen als auch auf Floating-Typen beziehen. Das Beispiel Nemo zeigt funktioniert, da Zeiger außerhalb dieser Klassifizierung liegen. Ganzzahlige Typen und Zeiger bilden skalare Typen.
– lccarrasco
9. Juli 2011 um 19:55 Uhr
Dies betrifft nicht a float
oder ein double
überhaupt, oder?
– SS Anne
13. Januar 2020 um 22:28 Uhr
Mir ist eine sehr praktische Anwendung des unären Plus-Operators bekannt: in Makros. Angenommen, Sie möchten so etwas tun
#if FOO > 0
Wenn FOO
undefiniert ist, erfordert die C-Sprache, dass es in diesem Fall durch 0 ersetzt wird. Doch wenn FOO
mit einer leeren Definition definiert wurde, führt die obige Direktive zu einem Fehler. Stattdessen können Sie Folgendes verwenden:
#if FOO+0 > 0
Und jetzt wird die Direktive syntaktisch korrekt sein, ob FOO
ist undefiniert, als leer definiert oder als ganzzahliger Wert definiert.
Ob dies die gewünschte Semantik liefert, ist natürlich eine ganz andere Frage, aber in einigen nützlichen Fällen wird es das.
Bearbeiten: Beachten Sie, dass Sie dies sogar verwenden können unterscheiden die Fälle von FOO
als Null definiert zu sein gegenüber als leer definiert, wie in:
#if 2*FOO+1 == 1
/* FOO is 0 */
#else
/* FOO is blank */
#endif
Sind Sie sicher, dass sich diese Präprozessordirektiven wirklich auf den unären +-Operator beziehen, wie er in C zu sehen ist? In Ihrem zweiten Beispiel mit einem Leerzeichen FOO
wäre der Ausdruck nicht gültig C.
– zneak
9. Juli 2011 um 23:45 Uhr
In der Tat tut es das. In jedem Fall das Betreiberpaar - -
(Leerzeichen erforderlich!) entspricht +
soweit ich das beurteilen kann, machen +
ziemlich überflüssig … Nein, das ist falsch, es ist nicht äquivalent, wenn der Operand ist INT_MIN
… 🙂
– R.. GitHub HÖR AUF, EIS ZU HELFEN
10. Juli 2011 um 2:49 Uhr
Entschuldigung, dass ich auf eine so alte Antwort stoße, aber ist dies nicht eher ein Beispiel für das binäre Plus als für das unäre Plus?
– Aurora Vollvik
2. November 2018 um 15:54 Uhr
@AuroraVollvik: Es ist ein unäres Plus, wenn das Makro zufällig definiert ist, aber eine leere Definition hat.
– R.. GitHub HÖR AUF, EIS ZU HELFEN
2. November 2018 um 16:15 Uhr
@UndefinedBehavior: Ob es unär oder binär ist, hängt davon ab, wie FOO
ist definiert.
– R.. GitHub HÖR AUF, EIS ZU HELFEN
7. Februar 2019 um 19:02 Uhr
Als Bhullar
Ich fand zwei Dinge so ungewöhnlich +
Betreiber tun ist
integer promotion
turning lvalue into rvalue
Beispiel für Integer-Promotion:
#include <stdio.h>
int main(void) {
char ch;
short sh;
int i;
long l;
printf("%d %d %d %d\n",sizeof(ch),sizeof(sh),sizeof(i),sizeof(l));
printf("%d %d %d %d\n",sizeof(+ch),sizeof(+sh),sizeof(+i),sizeof(+l));
return 0;
}
Typische Ausgabe (auf 64-Bit-Plattform):
1 2 4 8
4 4 4 8
lvalue in rvalue umwandeln beispiel:
int i=0,j;
j=(+i)++; // error lvalue required
Ja schon. Es ist hauptsächlich der Vollständigkeit halber vorhanden und um Konstruktionen wie diese etwas sauberer aussehen zu lassen:
int arr[] = {
+4,
-1,
+1,
-4,
};
Dies ist auf keinen Fall sauberer als die Alternative ohne das Unäre +
s.
– Ruola
13. Juni 2019 um 12:26 Uhr
Delan Azabani
Das Unäre +
Der Operator macht nur eines: es wendet die Integer-Promotions an. Da diese sowieso auftreten würden, wenn der Operand in einem Ausdruck verwendet würde, stellt man sich das unär vor +
steht in C einfach für Symmetrie mit unär -
.
Es ist schwierig, dies in Aktion zu sehen, weil die Werbeaktionen so allgemein angewendet werden.
Ich bin darauf gekommen:
printf("%zd\n", sizeof( (char) 'x'));
printf("%zd\n", sizeof(+(char) 'x'));
die (auf meinem Mac) druckt
1
4
Dies ist auf keinen Fall sauberer als die Alternative ohne das Unäre +
s.
– Ruola
13. Juni 2019 um 12:26 Uhr
Gemeinschaft
Was ist der Zweck des unären ‘+’-Operators in C?
Unäres Plus wurde C für Symmetrie mit unärem Minus von hinzugefügt Begründung für International Standard – Programmiersprachen – C:
Unäres Plus wurde vom C89-Komitee aus mehreren Implementierungen übernommen, um die Symmetrie mit unärem Minus zu gewährleisten.
und es ist keine No-Op, es führt die Integer-Promotions an seinem Operanden durch. Zitieren aus meiner Antwort auf Führt der Unary + -Operator Typkonvertierungen durch?:
Der Entwurf des C99-Standardabschnitts 6.5.3.3
Unäre arithmetische Operatoren sagt:
Das Ergebnis des unären +-Operators ist der Wert seines (heraufgestuften) Operanden. Die ganzzahligen Heraufstufungen werden am Operanden durchgeführtund das Ergebnis hat den heraufgestuften Typ.
Es lohnt sich, darauf hinzuweisen Kommentiertes C++-Referenzhandbuch (ARM) liefert den folgenden Kommentar zu unärem Plus:
Unary plus ist ein historischer Zufall und im Allgemeinen nutzlos.
In C++ wird es auch “missbraucht”, wenn a static_cast
würde die Absicht deutlicher zeigen, zum Beispiel das Auflösen einer mehrdeutigen Überladung des Funktionszeigers und der std::function für ein Lambda mit +
– Shafik Yaghmour
30. November 2017 um 16:46 Uhr
Nicht genau das gleiche, aber verwandt: stackoverflow.com/questions/727516/…
– jglouie
9. Juli 2011 um 19:33 Uhr
msdn.microsoft.com/en-us/library/s50et82s.aspx “Der unäre Plus-Operator vor einem Ausdruck in Klammern erzwingt die Gruppierung der eingeschlossenen Operationen. Er wird mit Ausdrücken verwendet, die mehr als einen assoziativen oder kommutativen binären Operator enthalten. Der Operand muss einen arithmetischen Typ haben. Das Ergebnis ist der Wert des Operanden. An ganzzahliger Operand wird ganzzahliger Heraufstufung unterzogen. Der Typ des Ergebnisses ist der Typ des heraufgestuften Operanden.”
– Tim S.
9. Juli 2011 um 19:36 Uhr
K&R sagt, dass es nur aus Symmetriegründen in den Standard aufgenommen wurde.
– Aaron Yodaiken
10. Juli 2011 um 2:44 Uhr
@ Jeremy: es gibt. Das sagt man zB
+short(1)
Typ hatint
nichtshort
.– MSalter
11. Juli 2011 um 10:19 Uhr
@TimS.: “Der unäre Plusoperator vor einem Ausdruck in Klammern erzwingt die Gruppierung der eingeschlossenen Operationen” — Oh? Es sind die Klammern, nicht die
+
das die Gruppierung erzwingt.– Keith Thompson
30. Juni 2013 um 22:24 Uhr