C Language                
            Punkty sekwencyjne
        
        
            
    Szukaj…
Uwagi
Międzynarodowa norma ISO / IEC 9899: 201x Języki programowania - C
Dostęp do lotnego obiektu, modyfikacja obiektu, modyfikacja pliku lub wywołanie funkcji wykonującej którąkolwiek z tych operacji to wszelkie skutki uboczne , które są zmianami w stanie środowiska wykonawczego.
Obecność punktu sekwencyjnego między oceną wyrażeń A i B oznacza, że każde obliczenie wartości i efekt uboczny związany z A jest sekwencjonowane przed każdym obliczeniem wartości i efektem ubocznym związanym z B.
Oto pełna lista punktów sekwencji z załącznika C internetowego projektu przed publikacją w 2011 r. Standardu języka C:
Punkty sekwencji
1 Poniżej przedstawiono punkty sekwencji opisane w 5.1.2.3:
- Między ocenami desygnatora funkcji a rzeczywistymi argumentami w wywołaniu funkcji i rzeczywistym wywołaniem. (6.5.2.2).
- Między ocenami pierwszego i drugiego argumentu następujących operatorów: logiczne AND
&&(6.5.13); logiczne OR||(6.5.14); przecinek,(6.05.17).- Między ocenami pierwszego argumentu warunkowego
? :operator i cokolwiek z drugiego i trzeciego argumentu jest oceniane (6.5.15).- Koniec pełnego deklaratora: deklaratory (6.7.6);
- Między oceną pełnego wyrażenia a następnym pełnym wyrażeniem do oceny. Oto pełne wyrażenia: inicjator, który nie jest częścią literału złożonego (6.7.9); wyrażenie w wyrażeniu wyrażeniowym (6.8.3); kontrolne wyrażenie instrukcji wyboru (
iflubswitch) (6.8.4); kontrolujące wyrażenie instrukcjiwhilelubdo(6.8.5); każde (opcjonalne) wyrażenie instrukcjifor(6.8.5.3); (opcjonalne) wyrażenie w instrukcjireturn(6.8.6.4).- Bezpośrednio przed powrotem funkcji biblioteki (7.1.4).
- Po działaniach związanych z każdym sformatowanym specyfikatorem konwersji funkcji wejścia / wyjścia (7.21.6, 7.29.2).
- Bezpośrednio przed i bezpośrednio po każdym wywołaniu funkcji porównawczej, a także między każdym wywołaniem funkcji porównawczej a każdym ruchem obiektów przekazywanych jako argumenty do tego wywołania (7.22.5).
Wyrażenia sekwencyjne
Sekwencjonowane są następujące wyrażenia:
a && b
a || b
a , b
a ? b : c
for ( a ; b ; c ) { ... }
 We wszystkich przypadkach wyrażenie a jest w pełni oceniane i wszystkie działania niepożądane są stosowane przed oceną b lub c . W czwartym przypadku oceniany będzie tylko jeden z b lub c . W ostatnim przypadku b jest w pełni oceniane, a wszystkie działania niepożądane są stosowane przed oceną c . 
 We wszystkich przypadkach ocena ekspresji a jest sekwencjonowana przed ocenami b lub c (alternatywnie oceny b i c są sekwencjonowane po ocenie a ). 
Tak więc wyrażenia takie jak
x++ && x++
x++ ? x++ : y++ 
(x = f()) && x != 0
for ( x = 0; x < 10; x++ ) { ... }
y = (x++, x++);
mają dobrze określone zachowanie.
Wyrażenia niesekwencjonowane
Następujące wyrażenia nie mają konsekwencji :
a + b;
a - b;
a * b;
a / b;
a % b;
a & b;
a | b;
 W powyższych przykładach wyrażenie a może być ocenione przed lub po wyrażeniu b , b może być ocenione przed a , lub nawet mogą być zmieszane, jeśli odpowiadają kilku instrukcjom. 
Podobna zasada dotyczy wywołań funkcji:
f(a, b);
 Tutaj nie tylko i a b są unsequenced (to znaczy , operator wywołania funkcji wywołuje punkt sekwencji), a także f , ekspresji, który określa funkcję, która ma być wykorzystane. 
Efekty uboczne można zastosować natychmiast po ocenie lub odłożyć na później.
Wyrażenia takie jak
x++ & x++;
f(x++, x++); /* the ',' in a function call is *not* the same as the comma operator */
x++ * x++;
a[i] = i++;
lub
x++ & x;
f(x++, x);
x++ * x;
a[i++] = i;
spowoduje niezdefiniowane zachowanie, ponieważ
- modyfikacja obiektu i każdy inny dostęp do niego muszą być zsekwencjonowane
- kolejność oceny i kolejność stosowania efektów ubocznych 1 nie jest określona.
1 Wszelkie zmiany stanu środowiska wykonawczego.
Wyrażenia nieokreślone sekwencyjnie
 Wywołania funkcyjne jako f(a) zawsze oznaczają punkt sekwencyjny między oceną argumentów i desygnatora (tutaj f i a ) a rzeczywistym wywołaniem. Jeśli dwa takie wywołania nie są konsekwentne, dwa wywołania funkcji są sekwencyjnie nieokreślone, to znaczy jedno jest wykonywane przed drugim, a kolejność jest nieokreślona. 
unsigned counter = 0;
unsingned account(void) {
   return counter++;
}
int main(void) {
   printf("the order is %u %u\n", account(), account());
}
 Ta niejawna podwójna modyfikacja counter podczas oceny argumentów printf jest poprawna, po prostu nie wiemy, które z wywołań jest pierwsze. Ponieważ zamówienie nie jest określone, może się różnić i nie można na nim polegać. Tak więc wydruk może być: 
kolejność wynosi 0 1
lub
kolejność wynosi 1 0
Analogiczne oświadczenie do powyższego bez wywołania funkcji pośredniej
   printf("the order is %u %u\n", counter++, counter++); // undefined behavior
 ma niezdefiniowane zachowanie, ponieważ nie ma punktu sekwencji między dwiema modyfikacjami counter .