2015-12-30 3 views
5

Diese Zeile kompiliert, wenn ich C++ verwenden, aber nicht C:Compiliert wie C++, aber nicht C (Fehler: L-Wert erforderlich als einstelliger '&' Operand)

gmtime(&(*(time_t *)alloca(sizeof(time_t)) = time(NULL))); //make an lvalue with alloca

Ich bin durch diesen Unterschied überrascht. Es gibt nicht einmal eine Warnung für C++.

Wenn ich gcc -x c angeben, die Nachricht ist:

playground.cpp:25:8: error: lvalue required as unary '&' operand 
gmtime(&(*(time_t *)alloca(sizeof(time_t)) = time(NULL))); 
     ^

Ist das nicht die & hier nur ein Adressoperator? Warum unterscheidet es sich in C und C++?

Obwohl ich zusammengesetzte Literale in C verwenden kann, ist es immer noch möglich, meine Syntax so zu ändern, dass sie sowohl in C & C++ funktioniert?

+2

Auch der Unterschied nicht etwa ist '&', so scheint es zu sein, ob '(* (time_t *) alloca (sizeof (time_t)) = Zeit (NULL)) 'ist ein Wert oder nicht. – immibis

+1

Warum schreibe ich das nicht einfach auf zwei Zeilen? 'time_t t = Zeit (NULL); gmtime (&t); ' – immibis

+0

@immibis hauptsächlich, weil ich eine Adresse eines temporären Objekts bekommen will (der' time_t' Wert wird nur einmal benutzt). Ich fand zusammengesetzte Literale in C so bequem, aber ich kann es nicht in C++ verwenden. – cshu

Antwort

8

In C11 6.5.16/3:

An assignment operator stores a value in the object designated by the left operand. An assignment expression has the value of the left operand after the assignment, but is not an lvalue.

In C++ 14 5,17/1:

The assignment operator (=) and the compound assignment operators all group right-to-left. All require a modifiable lvalue as their left operand and return an lvalue referring to the left operand.

(frühere Versionen der Sprachstandards jeweils angegebenen dasselbe) .

Da der Adressoperator auf einem L-Wert nur arbeiten kann, wird der Code in C ist richtig ++ nicht aber in C.


die Frage nach „Ist es möglich, meine Syntax zu ändern, damit es funktioniert in beiden C & C++? ". Dies ist kein wünschenswertes Ziel; die zwei Sprachen sind unterschiedlich und du solltest entscheiden, was du schreibst. Dies ist ungefähr so ​​sinnvoll wie der Versuch, bei der Syntax zu bleiben, die sowohl in C als auch in Java funktioniert.

Wie bereits von anderen vorgeschlagen, könnten Sie schreiben:

time_t t = time(NULL); 
gmtime(&t); 

, die die Vorteile gegenüber Ihrem ursprünglichen Code des Seins hat:

  • einfacher, daher leichter zu verstehen und zu pflegen
  • nicht hängen von Nicht-Standard alloca Funktion
  • hat keine mögliche Ausrichtungsverletzung
  • verwendet nicht mehr Speicher und vielleicht verbraucht weniger
+0

I don Ich kenne das Grundprinzip der Regel nicht, aber ich würde sagen, dass es ursprünglich in C nie ein Lvalue war (es gibt kaum einen Grund, das Ergebnis einer Aufgabe zu modifizieren), aber als C++ entwickelt wurde, änderten sie es in sei ein Lvalue für die Konsistenz mit Objekten, die 'operator =' überladen und einen Verweis auf self zurückgeben (was ein lvalue ist) –

+0

Guter Job.Ich wusste, dass es mit verschiedenen Regeln bezüglich Rvalues ​​und Lvalues ​​zu tun hatte, aber ich untersuchte den '&' Operator und nicht den '=' Operator. +1. – ApproachingDarknessFish

Verwandte Themen