2016-04-30 13 views
6

Ostatnio cppcheck podniesiony błąd w jakiś kod C, który ma strukturę:Czy kolejność oceny z operatorem przecinka i przypisaniem w języku C jest przewidywalna?

((void)(value_prev = value), value = new_value()) 

W większości przypadków można to podzielić na 2 linie, jednak istnieją pewne przypadki, to jest mieć w jednym rachunku.

W praktyce znalazłem, że działa to z popularnymi kompilatorami (GCC/Clang/MSVC), które nie dają żadnych ostrzeżeń (nawet z poziomami ostrzegawczymi ustawionymi na najwyższą wartość).


Przykładowy kod:

#include <stdio.h> 

int get_next(int i); 

int main() { 
    int i = 0, i_prev = 10; 
    do { 
     printf("%d\n", i); 
    } while ((void)(i_prev = i), 
      (i = get_next(i)) != 10); 
} 

CppCheck 1,73 (najpóźniej w momencie pisania) daje błąd z tym kodem:

(error) Expression '(void)(i_prev=i),(i=get_next(i))!=10' 
depends on order of evaluation of side effects` 

Chociaż kod może zostać zmieniony na spokój ostrzeżenie, czy porządek jest naprawdę nieokreślony?

+1

Czy to możliwe, że get_next (i) jest makrem, jak #define getnext (i) i ++? – gnasher729

+1

Nie, w tym przypadku jest to funkcja zdefiniowana, cppcheck podaje błąd w tym kodzie bez żadnych modyfikacji. – ideasman42

Odpowiedz

8

Porządek jest zdefiniowany, ponieważ istnieje między nimi punkt sekwencji. Patrz ISO/IEC 9899 6.5.17:

Lewy operand operatora przecinka jest oceniany jako wyrażenie nieważne ; po jego ocenie występuje punkt sekwencji. Następnie zostanie oceniony prawy operand; wynik ma swój typ i wartość. 95) Jeśli próba zmodyfikowania wyniku operatora przecinkowego lub uzyskania dostępu do niego po następnym punkcie sekwencyjnym, zachowanie jest niezdefiniowane.

Następnie dać wyraźny przykład:

w wywołaniu funkcji
f(a, (t=3, t+2), c)
funkcja ma trzy argumenty, z których druga ma wartość 5.

Nie jestem do końca pewien, dlaczego CppCheck go oflaguje.

+0

Czy punkt sekwencyjny nie jest C++? – Alex

+0

@Alex Jeśli tak, to C99 pożyczyło go od C++. Nie mam żadnych specyfikacji C przed porównaniem C99. –

Powiązane problemy