2009-05-07 5 views
7

Sytuacja: Sprawdź stan w C++ lub C# z wielu kryteriów:W językach C++ i C# są sprawdzane wiele warunków w ustalonej lub losowej kolejności?

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

Zawsze wierzyłem w jakiej kolejności te kontrole są przeprowadzane nie jest gwarantowana. Zatem niekoniecznie jest to pierwszy warunek1, a następnie warunek2, a dopiero potem warunek3. Nauczyłem się tego w moich czasach z C++. Myślę, że powiedziano mi o tym lub przeczytałem gdzieś.

Aż wiedzieć Zawsze bezpieczny kod napisany w celu uwzględnienia ewentualnych zerowych wskaźników w następującej sytuacji:

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

Więc pisałem:

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

bo nie byłem pewien, że Sprawdzanie not-null będzie uruchamiane jako pierwsze i tylko wtedy metoda instancji zostanie wywołana, aby wykonać drugą kontrolę.

Teraz nasze najwspanialsze umysły społeczności mówią mi, że kolejność przeprowadzania tych kontroli jest gwarantowana w kolejności od lewej do prawej.

Jestem bardzo zaskoczony. Czy to naprawdę tak w przypadku języków C++ i C#?

Czy ktoś jeszcze słyszał wersję, którą wcześniej słyszałem?

+1

Podwyrażenia w C# są oceniane od lewej do prawej, zawsze, kropka. Podwyrażenia w C/C++ są oceniane w kolejności w kolejności. Dwa wyrażenia w tym samym punkcie sekwencji mogą być oceniane w dowolnej kolejności. Wykonaj wyszukiwanie w sieci w "punkcie sekwencji", jeśli potrzebujesz formalnej definicji. –

Odpowiedz

14

Krótka odpowiedź od lewej do prawej z oceną zwarcia. Kolejność jest przewidywalna.

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

Niektóre języki oceniają wszystko w warunkach przed rozgałęzianiem (na przykład VB6).

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

Ref: MSDN C# Operators i ich kolejność lub pierwszeństwo.

+0

@Robert: Czy nie masz na myśli "Jeśli x nie jest Nothing && ..." (lub równoważną składnią VB6)? – RichieHindle

+1

@RichieHindle - tak, moje wspomnienie VB6/VBScript jest na szczęście bardzo stare. Zaktualizuję ponownie: –

2

Są one zdefiniowane jako oceniane od lewej do prawej, i, aby przestać oceniać, kiedy jeden z nich ocenia wartość fałsz. Dotyczy to zarówno C++, jak i C#.

0

Nie sądzę, że istnieje lub była jakakolwiek inna metoda. To byłoby jak kompilator decydujący o tym, by bez rozjaśnienia uruchamiać oświadczenia bez porządku. :) Teraz niektóre języki (jak VB.NET) mają różne operatory logiczne do zwarcia i braku zwarcia. Ale kolejność jest zawsze dobrze zdefiniowana w czasie kompilacji.

Oto operator precedence ze specyfikacji języka C#. Od spec ...

wyjątkiem operatorów przypisania, wszyscy operatorzy binarne są lewej asocjacyjne, co oznacza, że ​​ operacje wykonywane są od lewej do prawej . Na przykład x + y + z jest obliczany jako (x + y) + z.

+0

Znowu pierwszeństwo, asocjatywność i kolejność oceny podwyrażenia to trzy różne rzeczy. Nie można ustalić kolejności od pierwszeństwa w C#. –

+0

Żałuję również, że specyfikacja jest źle sformułowana w cytowanym tekście. Próbowałem to naprawić. –

+0

Tak, widzę twój punkt widzenia. Jest to sprzeczne z intuicją, ale przypuszczam, że operacja może pozostać skojarzona i nadal być oceniana od lewej do prawej. Oba muszą być ocenione przed rozpoczęciem operacji, więc pierwszeństwo niekoniecznie musi oznaczać kolejność oceny. Ale wtedy musiałbyś porzucić zwarcie jako zwarcie i nie działał (koniecznie) z dwoma operatorami i trzema operandami i || zwarcie nie działa z dwoma. –

0

Muszą być wykonywane od lewej do prawej. Pozwala to na sprawdzenie zwarcia.

Aby uzyskać więcej informacji, patrz Wikipedia article.

Powiązane problemy