2013-03-25 10 views
6

Mam zmienną globalną o nazwie var i funkcję foo. (Wiem, że jest złą praktyką, ale czasami jest to nieuniknione) Zastanawiam się, czy średnia C (ja kompilacji używając C99) mówi, co dzieje się z var jeśli próbuję wykonać:Zwracanie zmiennej przy użyciu przyrostu postu w C

long foo(){ 
    return var++; 
} 

Dzięki.

+0

Jego stara wartość jest zwracana, a zwiększana wartość jest przechowywana. –

+0

Tak. Wygląda na to, że działa zgodnie z oczekiwaniami. Po prostu nie jestem pewien, czy to jest właściwe, aby sądzić według standardu. – mgoszcz2

+1

W porządku - tak dobrze jak zmienne globalne. –

Odpowiedz

9

Krótka odpowiedź:

Powróci kopię var a następnie zaraz potem zwiększamy globalny var.

Długa odpowiedź:

C11 6.5.2.4

„Wynik Postfix ++ operator jest wartość argumentu jako efekt uboczny, wartość przedmiotu argumentu jest. inkrementował .. "./-/ Obliczenie wartości wyniku jest sekwencjonowane przed efektem ubocznym aktualizowania zapisanej wartości argumentu operacji.

Standard 5.1.2.3 „Realizacja programu” określa, że ​​wszystkie skutki uboczne musi być oceniana zanim program napotka punkt sekwencji. (Wiele informacji na temat punktów sekwencji można znaleźć here).

Istnieje punkt sekwencji po instrukcji return (C11 6.8/4).

Oznacza to, że wyrażenie var++ ma być całkowicie ocenione, zanim jakikolwiek kod w głównej() będzie kontynuowany.

Kod maszyna będzie wyglądać ten kod pseudo:

  • Store lokalna kopia var na stosie (albo w rejestrze itd)
  • Zwiększenie globalnego var z 1.
  • Return z podprogramu.
  • Użyj "copy-of-var".

Jeśli zamiast tego użyłeś przyrostu prefiksu, operacja zwiększania zostałaby zsekwencjonowana przed zapisaniem kopii.

+0

Warto chyba wspomnieć, że powyższy "kod maszynowy" pokazuje, dlaczego ++ na zmiennej globalnej nie jest bezpieczne dla wątków. Przełączanie kontekstowe między "kopiowaniem sklepu" a "zwiększeniem", które działa w 'var' (albo do odczytu lub zapisu), może spowodować nieoczekiwane zachowanie programu. – Lundin

2

foo() zwróci bieżącą wartość var, a var zostanie zwiększona.

4

Jak var++ jest postinkrementacja, to jest w zasadzie coś takiego:

long foo(){ 
    long tmp = var; 
    var++; 
    return tmp; 
} 

Jeśli używasz ++var zamiast powróci zwiększoną wartość (jak będzie to przyrost zmiennej przed powrocie jego wartość).

Powiązane problemy