valutazione delle espressioni in C
-
22-10-2019 - |
Domanda
Perché il seguente pezzo di codice C 12 12 12
Stampa
int main(int argc, char const *argv[]) {
int a = 2, *f1, *f2;
f1 = f2 = &a;
*f2 += *f2 += a += 2.5;
printf("%i %i %i\n", a, *f1, *f2);
return 0;
}
Soluzione
*f2 += *f2 += a += 2.5;
Questa linea ha indefinito Comportamento perché si modifica il valore di *f2
(cioè a
) più di una volta all'interno della stessa espressione senza un punto intermedio sequenza. UB significa che il programma può stampare "Ciao Mondo", si può bloccare, si possono stampare o 12 12 12
12 12 1029
o può iniziare a mangiare il cervello. Non fare affidamento su un comportamento indefinito.
Per citare lo standard C ++ (so che la questione è aggiunto C, ma non ho uno standard C da me e so che la stessa regola vale in C)
eccetto dove indicato, l'ordine di valutazione degli operandi dei singoli operatori e sottoespressioni dei singoli espressioni e l'ordine in cui gli effetti collaterali hanno luogo, è unspecified.53) tra il precedente e successivo punto di sequenza un oggetto scalare avrà il suo valore memorizzato modificato al più una volta dalla valutazione di un'espressione. Inoltre, il valore preventiva è accessibile solo per determinare il valore da memorizzare. I requisiti del presente paragrafo devono essere soddisfatti per ogni ordinamento ammissibile delle sottoespressioni di una piena espressione; altrimenti il ??comportamento è non definita ??em> .
Altri suggerimenti
Esso stampa lo stesso valore per tutti, perché si sta solo puntando alla variabile un int
:. a
esso stampa 12
perché a + 2.5 = 4
(a
è un int
), e poi lo si aggiunge a se stesso due volte.
@Downvoters: Perché così negativo? Credo che la mia risposta dice quello questo compilatore sta facendo su questo codice di esempio , che dovrebbe aiutare il PO capire il comportamento. Sono d'accordo che Armen Tsirunyan 's risposta è giusta (cioè dovrebbe ottenere il segno di spunta) e che il behaviour è definito secondo lo standard . Ma gli standard sono implementati, e ho ancora vedere un compilatore che compila il codice e poi, in fase di esecuzione, getta improvvisamente le sue mani e dice Undefined behaviour!
.
I perché *f2
e punto *f1
a a
(un intero).
Così *f2 = &a = 2
e *f1 = &a = 2
A questo punto si aggiunge ad un valore di 2.5
(perché a
è un numero intero, si ottengono 4
).
Quello che hai
a = 4
f2 = 4
f1 = 4
A questo punto si fa f2+f1+a = 12.