-------------------------------------------------------------------------------------------------- From: Maurizio Loreti Newsgroups: it.comp.lang.c Subject: Traduzione MOLTO LIBERA in italiano dalla Q/A 3.8 delle FAQ di comp.lang.c Date: 14 Oct 1999 12:21:38 +0200 -------------------------------------------------------------------------------------------------- Un "sequence point" e' una posizione temporale, all'interno della sequenza di istruzioni che costituisce un programma in C, nella e' garantito che tutti i side effects delle espressioni gia' incontrate abbiano avuto effetto. I sequence points sono: alla fine di ogni "full expression" (in parole povere, al punto e virgola); dopo gli operatori "||", "&&", "?:", e ","; e prima del richiamo delle funzioni. Lo Standard ANSI/ISO decreta che: "Tra due sequence points e' lecito modificare il valore in memoria di un oggetto al massimo una volta; ed il valore posseduto prima della modifica puo' essere letto solo per determinare il nuovo valore da scrivere in memoria". Il significato della seconda frase non e' immediato; significa in pratica che, se si scrive in memoria, ogni accesso in lettura all'oggetto modificato (e che avvenga all'interno degli stessi sequence points) deve PRECEDERE la modifica. Referenze: ISO Sec. 5.1.2.3, Sec. 6.3, Sec. 6.6, Annex C; Rationale Sec. 2.1.2.3; Harbison&Steele Sec. 7.12.1 pp. 228-9. Nella (precedente) `domanda 3.2 c'e' l'esempio di cui avevo parlato: 3.2: Con il mio compilatore, le istruzioni int i = 7; printf("%d\n", i++ * i++); stampano 49. Ma, qualunque sia l'ordine dei calcoli, non dovrei ottenere 56? (Risposta:) anche se gli operatori "postincremento" e "postdecremento" modificano il valore della variabile DOPO averne restituito il vecchio valore, il significato di questo "dopo" e' spesso frainteso. Non si garantisce che un incremento (o decremento) sia compiuto IMMEDIATAMENTE dopo l'accesso al valore precedente e PRIMA di qualunque altra operazione prevista dall'espressione all'interno della quale ci troviamo; si garantisce solo che l'aggiornamento della variabile sara' compiuto prima che l'espressione NELLA SUA TOTALITA' sia considerata "finita" (nella terminologia ANSI, prima del successivo "sequence point"). In questo esempio, evidentemente il compilatore ha deciso di eseguire prima la moltiplicazione e poi gli incrementi. Il comportamento di codice che contenga side effects multipli ed ambigui tra sequence points e' *indefinito*. In soldoni, con la frase "side effects multipli ed ambigui" si intende ogni combinazione di ++, --, =, +=, -= e cosi' via all'interno di una singola espressione, e che: o tenta di modificare due volte la stessa variabile; o sia di modificarla che di accedervi in lettura per utilizzarne il valore. Per una definizione piu' accurata, vedere il punto 3.8; e per il significato di "comportamento indefinito" il punto 11.3. E' inutile cercare di capire come il vostro compilatore si comporta in casi di questo genere, al contrario di quel che avviene nei malfatti e dannosi esercizi di qualche libro sul C; come e' saggiamante scritto nel K&R, "se non si sa come le cose avvengono al livello della macchina, questa ignoranza puo' solamente proteggervi". Referenze: K&R1 Sec. 2.12 p. 50; K&R2 Sec. 2.12 p. 54; ISO Sec. 6.3; H&S Sec. 7.12 pp. 227-9; CT&P Sec. 3.7 p. 47; PCS Sec. 9.5 pp. 120-1. --------------------------------------------------------------------------------------------------