2009-05-07 8 views
7

Situazione: condizione di controllo in C++ o C# con molti criteri:In C++ e C# ci sono più controlli di condizione eseguiti in una sequenza predeterminata o casuale?

if (condition1 && condition2 && condition3) 
{ 
    // Do something 
} 

Ho sempre creduto che la sequenza in cui vengono eseguiti questi controlli non è garantita. Quindi non è necessariamente prima condizione1 quindi condizione2 e solo allora condizione3. L'ho imparato nei miei tempi con il C++. Penso che mi sia stato detto o letto da qualche parte.

Fino a sapere che ho sempre scritto codice di sicurezza per tenere conto di eventuali puntatori nulli nella seguente situazione:

if ((object != null) && (object.SomeFunc() != value)) 
{ 
    // A bad way of checking (or so I thought) 
} 

Così stavo scrivendo:

if (object != null) 
{ 
    if (object.SomeFunc() != value) 
    { 
     // A much better and safer way 
    } 
} 

Perché io non ero sicuro del il controllo not-null verrà eseguito per primo e solo allora verrà chiamato il metodo di istanza per eseguire il secondo controllo.

Ora le nostre più grandi menti di comunità mi dicono che la sequenza in cui vengono eseguiti questi controlli è garantita per l'ordine da sinistra a destra.

Sono molto sorpreso. È davvero così per entrambi i linguaggi C++ e C#?

Qualcun altro ha sentito la versione che ho sentito prima?

+1

Le sottoespressioni in C# vengono valutate da sinistra a destra, sempre, punto. Le sottoespressioni in C/C++ vengono valutate in ordine di sequenza. Due espressioni nello stesso punto di sequenza possono essere valutate in qualsiasi ordine. Esegui una ricerca sul "punto di sequenza" se hai bisogno di una definizione formale. –

risposta

14

Breve risposta da sinistra a destra con valutazione del cortocircuito. L'ordine è prevedibile.

// perfectly legal and quite a standard way to express in C++/C# 
if(x != null && x.Count > 0) ... 

Alcune lingue valutano tutto nella condizione prima della diramazione (ad esempio VB6).

// will fail in VB6 if x is Nothing. 
If x Is Not Nothing And x.Count > 0 Then ... 

Rif: MSDN C# Operators e il loro ordine o la precedenza.

+0

@Robert: non intendi "Se x non è Nothing && ..." (o sintassi VB6 equivalente)? – RichieHindle

+1

@RichieHindle - sì, il mio ricordo di VB6/VBScript è per fortuna molto vecchio. Aggiornerò –

2

Sono definiti da valutare da sinistra a destra, e per interrompere la valutazione quando uno di questi viene valutato come falso. Questo è vero sia in C++ che in C#.

0

Non penso ci sia o sia stato in altro modo. Sarebbe come se il compilatore decidesse di eseguire dichiarazioni fuori ordine senza motivo. :) Ora alcuni linguaggi (come VB.NET) hanno diversi operatori logici per cortocircuiti e non cortocircuiti. Ma l'ordine è sempre ben definito al momento della compilazione.

Ecco lo operator precedence dalla specifica del linguaggio C#. Dal spec ...

Fatta eccezione per gli operatori di assegnazione, tutti gli operatori binari sono sinistra-associativa, il che significa che operazioni vengono eseguite da sinistra a destra . Ad esempio, x + y + z è valutato come (x + y) + z.

+0

Ancora, la precedenza, l'associatività e l'ordine di valutazione di sottoespressione sono tre cose diverse. Non è possibile determinare l'ordine dalla precedenza in C#. –

+0

Inoltre, mi spiace che le specifiche non siano formulate correttamente nel bit che hai citato. Ho cercato di sistemarlo. –

+0

Sì, capisco il tuo punto. È contro-intuitivo, ma suppongo che l'operazione possa essere lasciata-associativa e comunque valutata dall'ordine da sinistra a destra. Entrambi devono essere valutati prima che l'operazione possa essere applicata, quindi la precedenza non implica necessariamente l'ordine di valutazione. Ma poi si dovrebbe rinunciare al cortocircuito come cortocircuito e non funzionerebbe (necessariamente) con due operatori e tre operandi e || il cortocircuito non funzionerebbe con due. –

0

Devono essere eseguiti da sinistra a destra. Ciò consente di valutare il cortocircuito.

Vedere Wikipedia article per ulteriori informazioni.