2014-10-17 16 views
16

Non sono sicuro se la dichiarazione di sotto è ben definito dalla norma C o menoÈ * p ++ + = 2 ben definito?

*p1++ += 2; 

o altra dichiarazione simile:

*E1++ <operator>= E2 

Dalla serie C in merito a post-incremento:

Il risultato dell'operatore postfix ++ è il valore dell'operando. Dopo aver ottenuto il risultato, il valore dell'operando viene incrementato. (ovvero, viene aggiunto il valore 1 del tipo appropriato.) Consultare le discussioni degli operatori additivi e l'assegnazione composta per le informazioni su vincoli, tipi e conversioni e gli effetti delle operazioni sui puntatori. L'effetto collaterale dell'aggiornamento del valore memorizzato dell'operando deve avvenire tra la sequenza precedente e quella successiva .

E circa coumpund assegnazione:

Un'assegnazione composto della op modulo E1 = E2 differisce dalla semplice espressione assegnamento E1 = E1 op (E2) soltanto dal fatto che l'Ivalue E1 è valutato solo una volta.

+0

Beh, cosa ha scatenato il tuo sospetto che potrebbe essere indefinito? Per me, per esempio, tutto sembra a posto, il che mi rende difficile persino iniziare a rispondere alla domanda: non so su cosa concentrarmi. – AnT

+2

Non scrivere i codici in un progetto come questo, eccetto per la ricerca su di esso. – wshcdr

+9

Scrivere questo tipo di codice illeggibile solo per aggiungere altro codice su una riga è una cattiva programmazione. :) – Almo

risposta

23

Riscriviamo un po 'per renderlo più chiaro:

(*p1++) += 2 

così sarà dereferenziato il vecchio valore di p1, e 2 saranno aggiunti al suo referente. E p1 verrà incrementato dopo che è stato deferenziato (o almeno, dopo che il suo vecchio valore è stato caricato e in attesa di essere trasferito). Non c'è nessun problema qui: nessuno dei pezzi viene usato più di una volta.

Detto questo, si dovrebbe considerare riscrivere il codice per chiarezza:

*p1 += 2; 
++p1; 
+9

"allora" non è giusto, l'effetto collaterale di + = potrebbe accadere prima o dopo l'effetto collaterale di ++. La chiave è che si trovano su diversi oggetti scalari. – Cubbi

3

Postfix operatore di incremento (++) dà il valore di operando, cioè esso dà un r-value. Il valore r implica che sia utilizzato a sinistra dell'operatore di assegnazione (=) come operando.

int i = 0; 
i++ = 0 // [Error] lvalue required as left operand of assignment 

In caso di

*p1++ += 2; 

suffisso ++ non è applicata su *p1, ma viene applicato al puntatore p1++. Questo perché il suffisso ++ ha precedenza più alta di quella dell'operatore di derolleranza *. Così, compilatore analizzerà la dichiarazione di cui sopra come

*(p1++) += 2; 

e questo dice che:

  • *p1 devono essere valutati (per la produzione di una variabile) prima di aggiungere 2 e assegnando il risultato ad esso.
  • Il risultato da memorizzare in *p1 deve essere valutato prima dell'incremento su p1.
  • Una volta valutato *p1, è possibile incrementare p1 in qualsiasi momento.
+0

L'ultima dichiarazione è garantita in C++? – BlueTrin

+0

@BlueTrin; Sì. – haccks

+1

Avrei pensato che una volta valutato 'p1',' p1' può essere incrementato in qualsiasi momento. – BlueTrin