Wozu dient der unäre Plusoperator (+) in C?

Lesezeit: 7 Minuten

Benutzeravatar von zneak
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?

  • 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 hat intnicht short.

    – 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

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^31dann -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 FOOwä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 Benutzeravatar von Bhullar
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

Benutzeravatar von Delan Azabani
Delan Azabani

Nicht gerade ein No-Op

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

Benutzeravatar der Community
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

1419670cookie-checkWozu dient der unäre Plusoperator (+) in C?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy