Differenze di operatore condizionale tra C e C ++

Ho letto da qualche parte che l’operatore ?: In C è leggermente diverso in C ++, che c’è un codice sorgente che funziona in modo diverso in entrambe le lingue. Sfortunatamente, non riesco a trovare il testo da nessuna parte. Qualcuno sa cos’è questa differenza?

L’operatore condizionale in C ++ può restituire un lvalue, mentre C non consente funzionalità simili. Quindi, quanto segue è legale in C ++:

 (true ? a : b) = 1; 

Per replicare questo in C, dovresti ricorrere a if / else o gestire direttamente i riferimenti:

 *(true ? &a : &b) = 1; 

Anche in C ++, ?: E = operatori hanno uguale precedenza e gruppo da destra a sinistra , in modo tale che:

 (true ? a = 1 : b = 2); 

è un codice C ++ valido, ma genererà un errore in C senza parentesi attorno all’ultima espressione:

 (true ? a = 1 : (b = 2)); 

La principale differenza pratica è che in C, la valutazione di?: Non può mai risultare in un valore l dove, come in C ++, può farlo.

Ci sono altre differenze nella sua definizione che hanno poche conseguenze pratiche. In C ++ il primo operando viene convertito in un bool, in C viene confrontato con 0. Questo è analogo alla differenza nella definizione di ==,! =, Ecc. Tra C e C ++.

Esistono anche regole più complesse in C ++ per dedurre il tipo di un’espressione?: Basata sui tipi degli operandi 2a e 3a. Ciò riflette la possibilità di conversioni implicite definite dall’utente in C ++.

Codice di esempio C ++ valido; C. invalido

 extern int h(int p, int q); int g(int x) { int a = 3, b = 5; (x ? a : b) = 7; return h( a, b ); } 

gcc genera l’errore: “errore: lvalue non valido nell’assegnazione” durante la compilazione come C, ma il codice viene compilato senza errori durante la compilazione come C ++.

Modifica: Anche se: non è ansible restituire un valore l in C, forse sorprendentemente la grammatica per?: È:

 conditional-expression: logical-OR-expression logical-OR-expression ? expression : conditional-expression 

Ciò significa che a ? b : c = d a ? b : c = d analizza come (a ? b : c) = d anche se (a causa della regola ‘not an l-value’) questo non può portare a un’espressione valida.

C ++ cambia la grammatica a questo:

 conditional-expression: logical-or-expression logical-or-expression ? expression : assignment-expression 

Mentre l’estensione per consentire a espressioni condizionali di essere un valore-l in alcune situazioni avrebbe reso a ? b : c = d a ? b : c = d valido senza il cambio di grammatica, il nuovo cambiamento di grammatica significa che l’espressione è ora valida ma con il diverso significato di a ? b : (c = d) a ? b : (c = d) .

Anche se non ho alcuna prova per questo, suppongo che siccome il cambiamento di grammatica non potrebbe rompere la compatibilità con il codice C esistente, era più probabile che la nuova grammatica avrebbe prodotto meno sorprese con espressioni come:

 make_zero ? z = 0 : z = 1;