2013-06-05 28 views
25

Moje rozumienie jest nawiasami, nie ma znaczenia, więc czy istnieje jakikolwiek powód (inny niż "poprawa" jasności kodu), który Clang ostrzega o tym jako domyślny? Wolę nie dodawać nawiasów, ponieważ nie lubię dodawać kodu dla dobra kodu.Dlaczego Clang warn: `&& 'within' || '`?

src/websocket.c:420:43: warning: '&&' within '||' [-Wlogical-op-parentheses] 
     if (rv == 0 && N != 0 || rv == -1 && errno == ECONNRESET) { 
           ~~ ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~ 
src/websocket.c:420:43: note: place parentheses around the '&&' expression to 
     silence this warning 
     if (rv == 0 && N != 0 || rv == -1 && errno == ECONNRESET) { 
           ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~ 
+24

Co powiesz na dodanie kodu dla * jasności * sake? Nawiasy w tym miejscu pomogłyby ludziom, którzy nie pamiętają reguł o pierwszeństwie słów "&&" i "||" (które nie zawsze się pojawiają). – cHao

+3

Jestem za dodaniem kodu, aby poprawić przejrzystość. Osobiście jednak uważam, że dodatkowy szum wizualny niepotrzebnych nawiasów zmniejsza w tym przypadku klarowność. Kiedy widzę dodatkowe nawiasy, natychmiast skanuję całą linię szukając powodu dla nich, gdy nie znajduję żadnego, muszę wtedy zastanowić się przez chwilę, jeśli przeczytam to źle lub jeśli dany kod jest jedynie próbą "pomocy" mnie zrozumieć pierwszeństwo operatora, o którym już wiedziałem. Ten kod jest * zdecydowanie * nie dla niedoświadczonych programistów, większość osób czytających to będzie na moim poziomie, a więc zakładam, że będzie to samo. – mxcl

+2

Chociaż punkt dotyczący jasności jest ważny, wydaje się dziwne, aby ostrzegać o całkowicie legalnym kodzie zgodnie z regułami języka. –

Odpowiedz

25

Naturalną tendencją jest czytanie od lewej do prawej i łatwo zapomnieć o pierwszeństwie operatora. To powiedziawszy, to tylko ostrzeżenie, a jeśli wiesz, co robisz, a twój własny styl na to pozwala, możesz go stłumić.

+13

Dla tych, którzy chcieliby go pomijać, dodaj: "-Wno-logiczne-op-nawiasy" do CFLAGS twojego systemu konstrukcyjnego. – mxcl

20

Zgaduję, ponieważ jest to po prostu nieco niejasne, chyba że czytelnik jest bardzo dobry w C's operator precedence rules.

wyrażenia jest tak:

if (A && B || C && D) 

a od && ma wyższy precendence niż ||, oznacza to

if ((A && B) || (C && D)) 

co chyba jest to, co masz na myśli, ale to nie jest bardzo jasne podczas czytania .

+27

IMHO każdy, kto choć trochę studiował podstawową logikę, powinien pamiętać, że w matematyce ORA ma wyższy priorytet niż OR. Myślę, że kompilator jest tutaj dość paranoiczny. (I. e., To zdecydowanie nie to samo, co 'if (a = 0)'.) –

+12

Całkowicie się zgadzam - to najbardziej bezużyteczne ostrzeżenie, jakie kiedykolwiek widziałem. Dlaczego pozwala pisać 1 + 2 * 3 i nie sugeruje zmiany na 1+ (2 * 3)? –

+6

Prawdopodobnie dlatego, że w świecie rzeczywistym większość programistów jest całkiem pewna, co dokładnie robi '1 + 2 * 3', podczas gdy większość z nich nie jest pewna, co' a && b || c && d' zrobi dokładnie. – Drax