2016-11-24 68 views
8

Napisałem program, który zawiera listę błędów w zestawie danych i zwraca wartość logiczną na końcu (zwracanie wartości true oznacza, że ​​nie znaleziono żadnego błędu).Bitowe ORAZ z funkcją zwracającą bool w C++

Oto podsumowanie mojego kodu:

bool checkStuff1() {/*...*/} 
bool checkStuff2() {/*...*/} 
// ... 
bool checkStuffN() {/*...*/} 

bool checkAllStuff() 
{ 
    bool result = true; 
    result &= checkStuff1(); 
    result &= checkStuff2(); 
    // ... 
    result &= checkStuffN(); 
    return result; 
} 

mam zaufanie wartość result będzie w sam raz na koniec. Chciałbym jednak mieć pewność, że wszystkie funkcje są wywoływane (ponieważ wyświetlają komunikaty o błędach w przypadku błędu i chciałbym, aby wszystkie komunikaty o błędach zostały wydrukowane).

wiem, że gdybym napisał ten sposób, byłoby pominąć wszystkie checkStuffX() po pierwszym upadającego:

result = result && checkStuffX(); // Will not call checkStuffX() if result is already false 

Wiem też, że gdybym napisał w ten sposób, będzie to nazwać wszystkie checkStuffX() funkcje:

result = checkStuffX() && result; // Will always call checkStuffX() even if result is false 

Ale zastanawiałem się, czy zachowanie kodu, którego używam, z porównaniem bitowym, zostało określone i zagwarantowane przez standard?

Czy istnieje ryzyko niezdefiniowanego zachowania, w zależności od używanego kompilatora i jego optymalizacji?

+1

Możesz także użyć 'bool failed = false; failed | =! checkStuff1(); failed | =! checkStuff2(); ... failed | =! checkStuffN(); return! failed; '. Jest to zgodne z prostą zasadą (A && B) =! (! A ||! B) –

Odpowiedz

9

To jest w porządku.

Ocena zwarcia, do którego odnosi się użytkownik, dotyczy tylko operatorów && i ||.

+0

Powiązane: http://stackoverflow.com/questions/2488406/why-doesnt-c-have-or-for-booleans –

+0

Czy istnieje coś, co gwarantuje, że nie będzie żadnej oceny zwarcia (lub podobnej optymalizacji) w każdym przypadku z operatorem & =? Mam na myśli, że X & = Y z X == 0 zawsze kończy się na X == 0 niezależnie od wartości Y. Chciałbym być pewien, że niezależnie od tego, jaki kompilator zostanie użyty, zachowanie będzie wszędzie takie samo, i Y() zostanie wywołany, jeśli jest funkcją. Czy jest coś w standardach, które to gwarantuje? – teupoui

+0

Tak, jest to zagwarantowane przez definicję algebry Boole'a. Jeśli wszystkie bity w jednym operandzie wynoszą 0, wynik bitowego operatora '&' ma wartość 0. –

0

To zadziała, chociaż konwersja int < -> bool może spowodować problemy z wydajnością, jeśli masz wiele czeków. Och, możesz skorzystać ze wskaźników funkcji i pętli, jeśli wszystkie funkcje mają ten sam typ.

bool (*checks[])(void)= {checkStuff1, checkStuff2 ... checkStuffN}; 

bool result = true; 
for (int i = 0; i < sizeof(checks)/sizeof(checks[0]); result = checks[i++]() && result); 

kod wyglądałby prostsze, jeśli można użyć wahała dla() - jak for(auto i : checks). Zaletą tego, jeśli procedura ta została zadeklarowana gdzieś indziej w kodzie, należy usunąć lub dodać krok, wystarczy zmodyfikować deklarację tablicy (lub program może ją zmienić, skutecznie zmieniając przepływ pracy!). Minusem - nie można go używać z czekami, które mają różne prototypy.

+0

To by mi nie pomogło w moim przypadku ...Uprościłem moje pytanie: funkcje sprawdzające za każdym razem przyjmują różne parametry. Ale i tak dzięki ! – teupoui