Non capisco cosa viene passato alla funzione f () quando lo chiamo in questo modo.
main()
{
void f(int,int);
int i=10;
f(i,i++);
}
void f(int i,int j)
{ printf("%d %d",i,j); }
mi dà 11 10. Qualcuno può spiegare perché il suo 11?
Non capisco cosa viene passato alla funzione f () quando lo chiamo in questo modo.
main()
{
void f(int,int);
int i=10;
f(i,i++);
}
void f(int i,int j)
{ printf("%d %d",i,j); }
mi dà 11 10. Qualcuno può spiegare perché il suo 11?
Il comportamento non è definito, come segue:
Dallo standard C99:
6.5 Expressions
...
2 Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression.72) Furthermore, the prior value shall be read only to determine the value to be stored.73)
72) A floating-point status flag is not an object and can be set more than once within an expression.
73) This paragraph renders undefined statement expressions such aswhile allowingi = ++i + 1; a[i++] = i;
i = i + 1; a[i] = i;
Stiamo violando la seconda frase di quel paragrafo; siamo non semplicemente leggendo il valore precedente per determinare il nuovo valore da memorizzare.
Nota che indefinito non significa necessariamente illegale . Undefined significa semplicemente che il compilatore è libero di gestire la situazione nel modo che ritiene opportuno; qualsiasi risultato è considerato "corretto". Potresti benissimo finire con il risultato che ti aspettavi. O no. Il programma potrebbe bloccarsi. O no. O qualsiasi altra cosa potrebbe accadere.
In questo caso, otterrai risultati diversi in base a piattaforma, compilatore, impostazioni di ottimizzazione, codice circostante, ecc. Il motivo per che è il seguente:
6.5.2.2 Function calls
...
10 The order of evaluation of the function designator, the actual arguments, and subexpressions within the actual arguments is unspecified, but there is a sequence point before the actual call.
Non è specificato se i
o i++
viene valutato per primo; inoltre, non è specificato se l'effetto collaterale di ++
viene applicato immediatamente dopo la valutazione di i++
, come segue:
6.5.2.4 Postfix increment and decrement operators
...
2 The result of the postfix++
operator is the value of the operand. After the result is obtained, the value of the operand is incremented. (That is, the value 1 of the appropriate type is added to it.) See the discussions of additive operators and compound assignment for information on constraints, types, and conversions and the effects of operations on pointers. The side effect of updating the stored value of the operand shall occur between the previous and the next sequence point.
Enfasi sulla mia.
Modifica
Modificato leggermente la dicitura per chiarire che il comportamento è non definito .
Perché un comportamento indefinito, ecco perché. Si legge il valore due volte e lo si modifica una volta senza punto di sequenza intermedio, che è una pila gigantesca di illegali. Anche se non fosse illegale, il compilatore non ha alcun obbligo di valutare gli argomenti della tua funzione in un ordine particolare, o addirittura di valutarne uno completamente prima di valutarne un altro.
L'ordine di valutazione degli argomenti delle funzioni non è specificato e quindi 11 10
è un output corretto possibile.