2013-04-28 6 views
6

La mia comprensione dell'intera sequenza di punti è fondamentale. Tutto ciò che ho è un'idea cruda intuitiva che "una volta che si incontra un punto di sequenza, possiamo essere sicuri che tutti gli effetti collaterali delle valutazioni precedenti sono completi". Ho letto anche che in dichiarazioni come printf("%d",a++,++a,a++) il comportamento non è definito in quanto una virgola non indica un punto di sequenza mentre un punto e virgola lo fa. Quindi, invece di fare supposizioni e andare per intuizione, sento che una risposta molto rigorosa e conclusiva mi aiuterà molto.Esistono problemi di "sequenza" con istruzioni come "int a = 4, * ptr = & a;" o "x + = 4, y = x * 2;"?

Così sono i seguenti tipi di dichiarazioni sicuro & certo in C:

int a=4,*ptr=&a; //Statement 1 

x+=4,y=x*2; //Statement 2 (Assume x and y are integer variables) 

Se sì, come? Soprattutto nel secondo caso, se una virgola non è un punto di sequenza, come possiamo essere certi chesia stato incrementato diprima di utilizzarlo nell'assegnazione y=x*2? E per la prima affermazione, come posso essere sicuro che a è stato inizializzato e assegnato memoria prima di assegnare il suo indirizzo a ptr? Dovrei giocare sicuro e utilizzare il seguente per quanto sopra:

int a=4,*ptr; 
ptr=&a; 

e

x+=4; 
y=x*2; 

Modifica La mia comprensione del l'operatore virgola mi dice che tali dichiarazioni sono sicuri. Ma dopo aver letto sui punti di sequenza e su come qualcosa come printf("%d",a++,++a,a++) non è definito, ho dei ripensamenti.

+0

',' non è un punto di sequenza in 'printf ("% d ", a ++, ++ a, a ++)' ma è uno in 'x + = 4, y = x * 2;'. E 'int a = 4, * ptr = & a;' non è un'affermazione. –

+0

@PascalCuoq Che cos'è 'int a = 4, * ptr = & a;' allora? Non dichiara e inizializza 'a' e' ptr'? –

+0

@PascalCuoq 'int a = 4, * ptr = & a;' dopo tutto è corretto, giusto? –

risposta

12

La virgola che separa gli argomenti della funzione in una chiamata di funzione è non un operatore virgola - è solo la punteggiatura che si scrive nello stesso modo dell'operatore virgola. Non esiste un punto di sequenza tra la valutazione di argomenti di funzioni differenti, quindi è per questo che si ottiene UB in quel caso.

D'altra parte, nella vostra espressione:

x+=4,y=x*2; 

la virgola qui è un operatore virgola, che introduce un punto di successione; non c'è UB.

In una dichiarazione, anche la virgola tra i dichiaratori non è un operatore virgola; tuttavia, la fine di un completa dichiaratore (un dichiaratore non parte di un'altra declarator) non introduce un punto sequenza, così come una dichiarazione:

int a = 2, b = a + 1; 

non è UB.

3

Non c'è UB qui.
Come da C99 serie:

C. L'allegato C (informativa): Sequenza punti
# 1 Di seguito sono riportati i punti di sequenza descritti in 5.1.2.3:
- La chiamata a una funzione, dopo che gli argomenti sono stati valutati (6.5.2.2).
- La fine del primo operando dei seguenti operatori: logico AND & & (6.5.13); OR logico || (6.5.14); condizionale? (6.5.15); comma, (6.5.17).

Quindi non c'è operatore virgola coinvolto nella chiamata di funzione. Nonostante la presenza di virgola.

+0

@Mat Right. Aggiunto C qote. – alexrider

+0

@Mat Puoi per favore dare una risposta più semplice? Questo è un po 'duro per me. –

+1

@SheerFish: il ',' che separa gli argomenti della funzione non è l'operatore virgola. L'operatore virgola introduce un punto di sequenza. Quello tra gli argomenti della funzione no, è solo la sintassi. – Mat