Punkty sekwencji i efekty uboczne: Cicha zmiana w C11?

C99 § 6.5Wyrażenia

(1) Wyrażenie to sekwencja operatorów i argumentów, która określa obliczanie wartości lub wyznacza obiekt lub funkcję lub generuje efekty uboczne lub wykonuje ich kombinację.

(2) Pomiędzy poprzednim i następnym punktem sekwencji obiekt powinien mieć zapisaną wartość co najwyżej raz przez ocenę wyrażenia.72) Ponadto wartość wstępna powinna być odczytywana tylko w celu określenia wartości, która ma być przechowywana.73)

z przypisami

72) Flaga stanu zmiennoprzecinkowego nie jest obiektem i może być ustawiona więcej niż jeden raz w wyrażeniu.

73) Ten akapit oddaje niezdefiniowane wyrażenia instrukcji, takie jak

    i = ++i + 1;
    a[i++] = i;

pozwalając

    i = i + 1;
    a[i] = i;

gdzie C11 § 6.5 zmieniono na (tekst (1) ma dodatek):

(1) […] Obliczenia wartości argumentów operatora są sekwencjonowane przed obliczeniem wartości wyniku operatora.

(2) Jeśli efekt uboczny na obiekcie skalarnym nie zostanie wyodrębniony względem innego efektu ubocznego na tym samym obiekcie skalarnym lub obliczenia wartości przy użyciu wartości tego samego obiektu skalarnego, zachowanie jest niezdefiniowane. Jeśli istnieje wiele dopuszczalnych kolejności podwyrażeń wyrażenia, zachowanie jest niezdefiniowane, jeśli taki niesekwencjonowany efekt uboczny wystąpi w którymkolwiek z porządków.84)

gdzie przypis 84 w C11 jest taki sam jak 73 w C99.

Jestem trochę zdezorientowany… Czytam C11 (2) jako „[…] albo (inny efekt uboczny na tym samym obiekcie skalarnym) lub (obliczanie wartości przy użyciu wartości tego samego obiektu skalarnego) […]”, które wydaje się nawet nie pozwolićfoo = ++i (istnieje efekt uboczny i używamy wartości w zależności od zmienionego obiektu). Jednak nie jestem native speakerem, więc byłoby miło, gdyby można było mi powiedzieć, jak to zdanie powinno zostać „sparsowane”. Rozumiem C99, ale nie do końca rozumiem brzmienie C11.

W każdym razie rzeczywiste pytanie: czy jest to zmiana z C99 na C11, czy te sformułowania są równoważne? A jeśli tak, to dlaczego został zmieniony? A jeśli nie, to czy ktoś mógłby podać przykład wyrażenia UB w C99, ale nie w C11 lub odwrotnie?

questionAnswers(4)

yourAnswerToTheQuestion