2014-10-19 25 views
6

ho un pezzo di codice in C proposta come segue:errori usando operatore ternario in c

main() 
{ 
    int a=10, b; 
    a>=5 ? b=100 : b=200 ; 
    printf("%d" , b); 
} 

esecuzione del codice sul compilatore gcc in unix genera l'errore di compilazione come 'lvalue richiesto come operando sinistro di incarico 'e punta l'errore su b = 200 mentre in Windows la compilazione tramite Turbo C dà 200 come output.

Qualcuno può spiegare cosa sta succedendo esattamente in questo caso?

+6

utilizzare le parentesi per chiarire la precedenza dell'operatore che si desidera. (E non usare Turbo C. Ha più di 20 anni!) –

+1

http://stackoverflow.com/questions/12068118/use-of-brackets-in-expression-that-include-ternary-operator –

risposta

-7

Prova questo! Perché l'operatore ternario restituisce il valore che devi assginare a b!

#include <stdio.h> 

main() { 

    int a = 10, b; 
    b = a >= 5 ? 100 : 200; 
    printf("%d" , b); 

} 
+0

Grazie .. ma la mia domanda riguardava la risposta variata dello stesso codice in due compilatori diversi. Potete per favore elaborare questo punto? Grazie ancora :) – user3778845

+3

@ Rizier123: non è indefinito. –

2

si può mettere tra parentesi graffe per farlo funzionare .. come

(a>=5)?(b=100):(b=200); 

e si prega di assegnare un tipo di ritorno per la funzione main()

14

In C l'operatore ternario è definito come

logico-OR-espressione? espressione: condizionale espressione

dove espressione condizionale è definito come

logical-OR-expression 

L'operatore di assegnazione ha una priorità inferiore rispetto l'operatore OR. Così si deve scrivere

a >= 5 ? b = 100 : (b = 200); 

In caso contrario, il compilatore consideres l'espressione come

(a >= 5 ? b = 100 : b) = 200; 

Come il risultato di l'operatore ternario in C non è un lvalue allora l'espressione di cui sopra non è valido e il compilatore emette un errore.

Dalla C standard:

il risultato è il valore del secondo o terzo operando (qualunque è valutata), convertito al tipo descritto di seguito

e nota:

110) Un'espressione condizionale non produce un lvalue.

Prendere in considerazione l'esistenza di una differenza essenziale tra la definizione dell'operatore in C e C++. In C++ è definito come

logico-o-espressione?espressione: assegnamento espressione

In C++ stesso GCC compila il codice correttamente

#include <iostream> 

int main() 
{ 
    int a = 10, b; 

    a >= 5 ? b = 100 : b = 200; 

    std::cout << "b = " << b << std::endl; 

    return 0; 
} 
+0

Grazie :-) ... – user3778845

+0

Non è il doppio di quella domanda? Ho chiuso in modo errato con questo?: Http://stackoverflow.com/a/6966331/1275169 –

+0

@Blue Moon Se non mi sbaglio in queste domande vengono considerate diverse parti dell'operatore. Quindi penso che si aggiungano l'un l'altro. –

1

Questo errore è causato dalla sintassi del condizionale espressione che è

logical-OR-expression ? expression : conditional-expression 

Pertanto, la parte successiva allo : deve essere in grado di analizzare b = 200. Tuttavia, conditional-expression non può analizzare che, a causa un'espressione di assegnazione ha meno la precedenza - si avrebbe bisogno di mettere una parentesi intorno all'espressione assegnazione

a>=5 ? b=100 : (b=200); 

Ma il fatto che avete bisogno di una parentesi fa non significa che l'espressione altrimenti viene analizzato come (a>=5 ? b=100 : b) = 200, è solo un artefatto interno del compilatore che nel messaggio di errore parla dell'operando sinistro dell'assegnazione. Il linguaggio C ha le seguenti due regole per la sintassi delle espressioni di assegnazione, e la regola che corrisponde viene applicata

conditional_expression 
unary_expression '=' assignment_expression 

Questo interferisce con il parser discesa ricorsiva, che avrebbe semplicemente invocare parseConditionalExpression, e verificare ciò che segue di token. Pertanto alcune implementazioni del parser C scelgono di non dare qui un errore di sintassi, ma lo analizzano come se la grammatica dicesse conditional_expression '=' ... sopra, e in seguito quando ispeziona l'albero di analisi, convalidi che il lato sinistro sia un lvalue. Ad esempio, il codice sorgente Clang dice

/// Note: we diverge from the C99 grammar when parsing the assignment-expression 
/// production. C99 specifies that the LHS of an assignment operator should be 
/// parsed as a unary-expression, but consistency dictates that it be a 
/// conditional-expession. In practice, the important thing here is that the 
/// LHS of an assignment has to be an l-value, which productions between 
/// unary-expression and conditional-expression don't produce. Because we want 
/// consistency, we parse the LHS as a conditional-expression, then check for 
/// l-value-ness in semantic analysis stages. 

E il codice sorgente del parser GCC dice

/* ... 
In GNU C we accept any conditional expression on the LHS and 
diagnose the invalid lvalue rather than producing a syntax 
error. */