5

Comment expliquer la sortie du code ci-dessous:C - Explication de sortie de printf ("% d% d n", k = 1, k = 3);

include <stdio.h> 

int main(void) { 
    int k; 
    printf("%d %d\n",k=1,k=3); 
    return 0; 
} 

Ideone Link

Ma pensée est que 1 sera affecté à k variable, puis 1 seront imprimés. De même 3 sera affecté à k et la sortie sera 3.

Résultats escomptés

1 3 

de sortie réelle

1 1 

J'extrapolant à partir

int a; 
if (a = 3) { 
    ... 
} 

est égal à

if (3) { 
    ... 
} 

Veuillez me faire savoir où je me trompe?

+0

@CinCout Désolé, je remarquai tard. –

Répondre

7

Le problème est que l'ordre d'évaluation des arguments de la fonction n'est pas défini et qu'il n'y a pas de point de séquence entre l'évaluation ou les arguments. Ainsi, cette déclaration

printf("%d %d\n",k=1,k=3) 

invoque undefined behavior, comme vous essayez de modifier la même variable plus d'une fois sans point de séquence entre les deux.

Une fois qu'un programme appelant UB est exécuté et (si) il y a une sortie, il ne peut pas être justifié de toute façon, la sortie peut être n'importe quoi.

+1

c'est très bien, une affectation, va imprimer la valeur de 'k', c'est-à-dire, 3. –

+0

Je pense que cette réponse est fausse http://stackoverflow.com/a/9514591/5473170. Peux-tu le vérifier. –

+0

@SurajJain Ce n'est pas le meilleur, mais ça a l'air bien, en général. Pourquoi pensez-vous que c'est incorrect? –

-4

Je suppose que la raison pour laquelle vous voyez 1 1 est parce que les deux instructions d'affectation sont en train de passer le contrôle est passé à printf.

printf("%d %d\n",k=1,k=3); 

Donc, en réponse aux bas-voix, oui, ce comportement est indéfini, et donc vous ne devriez pas compter sur ce comportement continue. Cependant, pour ce qui est d'identifier pourquoi la sortie était 1 1 et non 1 3, nous pourrions déduire que l'affectation de 3 a peut-être été écrasée par une affectation ultérieure de 1. Lorsque printf est appelé, la pile d'appels contient deux entrées contenant la valeur finale de k, à savoir 1

Lorsque printf est appelée, la pile d'appels contient deux entrées contenant la valeur finale k.

Vous pouvez tester cela en remplaçant ceux par une fonction qui imprime quelque chose lors de son exécution.

Exemple de code:

#include <stdio.h> 

int test(int n) { 
    printf("Test(%d)\n", n); 
    return n; 
} 

int main(void) { 
    int k; 
    printf("%d %d\n",k=test(1), k=test(3)); 
    return 0; 
} 

Sortie:

Test(3) 
Test(1) 
1 1 
+0

Ceci est une mauvaise explication à une raison probablement beaucoup plus artificielle –

+1

@ q.Phen pauvre est un mot doux, c'est faux. –

+0

Je suis vraiment curieux de savoir comment mon explication est fausse. L'argument est-il juste que l'assignation multiple est UB? – Scovetta