2015-12-30 42 views
5

Linia ta kompiluje kiedy używać C++, ale nie C:Kompiluje jak C++, ale nie C (błąd: lwartość wymagane jednoargumentowego '&' argumentu)

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

Jestem zaskoczony tej różnicy. Nie ma nawet ostrzeżenia dla C++.

Kiedy określić gcc -x c komunikat brzmi:

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

nie jest & tutaj tylko adresu wykonawcy? Dlaczego jest inaczej w C i C++?

Chociaż mogę używać literałów złożonych w języku C, czy nadal można zmodyfikować moją składnię, aby działała zarówno w C & C++?

+2

Również różnica nie chodzi o '&' wydaje się być o tym, czy '(* (time_t *) alloca (sizeof (time_t)) = czas (null)) 'jest lwartością lub nie. – immibis

+1

Ponadto, dlaczego nie pisać tego w dwóch liniach? 'time_t t = time (NULL); gmtime (&t); ' – immibis

+0

@imibi głównie dlatego, że chcę uzyskać adres tymczasowego obiektu (wartość' time_t' jest używana tylko raz) .Znalazłem złożone literały w C tak wygodne, ale nie mogę go używać w C++. – cshu

Odpowiedz

8

W C11 5.6.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.

w 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.

(wcześniejsze wersje norm językowych w każdym przypadku podano to samo) .

Ponieważ adresu wykonawcy, może działać tylko na lwartością kod jest prawidłowy w C++, ale nie w C.


Jeśli chodzi o pytanie „Czy jest możliwe aby zmodyfikować moje składni, aby pracować zarówno w C & C++? ". To nie jest pożądany cel; dwa języki są różne i powinieneś zdecydować, co piszesz. To ma tyle samo sensu, co próba trzymania się składni działającej zarówno w języku C, jak i Java.

Jak sugerowano przez innych, można napisać:

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

który ma zalety nad oryginalnym kodzie jest:

  • prostsze, więc łatwiejsze do zrozumienia i utrzymania
  • nie zależy od niestandardowej funkcji alloca
  • nie ma potencjalnego naruszenia linii trasowania
  • wykorzystuje nie więcej pamięci i może zużywa mniej
+0

znając uzasadnienie reguły, ale domyślam się, że pierwotnie w C to nigdy nie było l-wartości (rzadko istnieje jakakolwiek przyczyna, aby spróbować zmodyfikować wynik zadania), ale kiedy C++ było rozwijane, oni zmienili to na być lwartością dla spójności z obiektami, które przeciążają 'operator =' i zwracają odniesienia do siebie (co jest lwartością) . –

+0

Dobra robota.Wiedziałem, że ma to związek z różnymi regułami dotyczącymi wartości r i wartości l, ale szukałem operatora '&', a nie operatora '='. +1. – ApproachingDarknessFish