30

squalyl> ton exemple se trouve donner ce résultat. Ca ne veut absolument pas dire qu'utilisé différememnt il aura le même comportement.
De fait, la seule garantie est celle indiquée par la norme. Tout autre code donnera un résultat indéfini (entendre par là qu'il donnera bien un résultat, mais qui peut changer selon le compilateur et la version, et que ce résultat peut potentiellement être de planter, de formater ton disque dur ou de transformer ton pc en cafetière).
Pollux (./26) :
Ben non, les deux sont du code invalide (enfin, invalide seulement s'il est exécuté, bien sûr), autrement dit non seulement le résultat n'est pas défini mais en plus ça peut très bien planter ^^

Je suis curieux de connaître ta source, parce que je vois nulle part indiqué que c'est invalide. Il est possible que ce soit un oubli, parce que pour l'opérateur d'assignation c'est bien spécifié que c'est non défini. En revanche pour l'opérateur de postincrémentation il n'y a pas de telle remarque.
[3 minutes plus tard]
Ah voilà c'est bon j'ai trouvé : "Between the previous and next sequence point an object shall have its stored value
modified at most once by the evaluation of an expression.
".
C'était dans la définition même d'une expression, et pas du côté des assignations smile

Du coup, x++ + x++ est bien illégal.
En revanche, putc(x++) || putc(x++) est légal et incrémente x une fois avant l'appel au premier putc, et une fois entre le || et l'appel au second putc.

31

je savais pas qu'il existait des codes syntaxiquement ET sémantiquement corrects mais invalides. Pourquoi le compilateur ne geule pas? Godzil, t'as testé ce qu'il dit gcc, avec -W -Wall ?

32

Testé avec Visual C++ 6 :

#include <stdio.h>

int main(int argc, char* argv[])
{
   int x, z;
   x = 1; z = 0;
   printf("x = %d | z = %d\n", x, z);
   z = (x++) + (x++);
   printf("x = %d | z = %d\n", x, z);

   z = x++ + x++;
   printf("x = %d | z = %d\n", x, z);

   z = x + (x++);
   printf("x = %d | z = %d\n", x, z);

   z = x + x++;
   printf("x = %d | z = %d\n", x, z);


   return 0;
}


donne


x = 1 | z = 0
x = 3 | z = 2
x = 5 | z = 6
x = 6 | z = 10
x = 7 | z = 12
Press any key to continue


et 0 erreurs, 0 warnings

(enfin si 2 :

Compiling...
StdAfx.cpp
Compiling...
test.cpp
C:\dev\test\test.cpp(9) : warning C4100: 'argv' : unreferenced formal parameter
C:\dev\test\test.cpp(9) : warning C4100: 'argc' : unreferenced formal parameter
Linking...

test.exe - 0 error(s), 2 warning(s)


trigic



Avec optimisations (max speed):

x = 1 | z = 0
x = 3 | z = 2
x = 5 | z = 6
x = 6 | z = 10
x = 7 | z = 12
Press any key to continue



Avec optimisation (Min Size):

x = 1 | z = 0
x = 3 | z = 2
x = 5 | z = 6
x = 6 | z = 10
x = 7 | z = 12
Press any key to continue


Toutes optimisations :
x = 1 | z = 0
x = 3 | z = 2
x = 5 | z = 6
x = 6 | z = 10
x = 7 | z = 12
Press any key to continue


(j'ai presque l'impression de me repeter..)

avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

33

A mon avis, dans les références officielles, ces comportements sont indéfinis
Mais les implémenteurs de compilos se sont vite dépêchés de le définir pour éviter les soucis
et on dirait qu'ils sont d'accord grin

34

mtrapier@prod-500 /cygdrive/c/dev/test $ gcc --version
gcc (GCC) 3.3.3 (cygwin special)
Copyright (C) 2003 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

mtrapier@prod-500 /cygdrive/c/dev/test $ gcc test.c -o test -W -Wall
test.c: In function `main':
test.c:9: warning: unused parameter `argc'
test.c:9: warning: unused parameter `argv'
mtrapier@prod-500 /cygdrive/c/dev/test $ ./test
x = 1 | z = 0
x = 3 | z = 2
x = 5 | z = 6
x = 6 | z = 10
x = 7 | z = 12
mtrapier@prod-500 /cygdrive/c/dev/test $


(j'ai pas fait de cat de test, mais bon tout le monde a compris que c'était le meme fichier)
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

35

C'est quand même dommage que ce soit à toi Godzil, qu'il faille rappeler qu'on ne prouve pas un "pour tout" par des exemples.
squalyl (./31) :
je savais pas qu'il existait des codes syntaxiquement ET sémantiquement corrects mais invalides. Pourquoi le compilateur ne geule pas? Godzil, t'as testé ce qu'il dit gcc, avec -W -Wall ?
Parce que le compilateur a le droit de faire strictement ce qu'il veut lorsqu'il croise ce genre de code invalide. S'il a envie de le compiler en system("rm -rf /"), il en a tout à fait le droit. Du coup, la détection de ce genre d'erreurs étant difficile et pas toujours souhaitable selon le contexte, il ne le fait pas.
squalyl (./33) :
A mon avis, dans les références officielles, ces comportements sont indéfinis
Mais les implémenteurs de compilos se sont vite dépêchés de le définir pour éviter les soucis
et on dirait qu'ils sont d'accord biggrin.gif
Ben par définition, quand tu implémentes tu définis ce qui se passe. Simplmeent, tu es libre de faire ce que tu veux pour les comportements indéfinis. Certains décident de remonter une erreur, d'autres d'en profiter pour optimiser, d'autres encore sortent un résultat qu'ils estiment logique... tu n'as absolument aucune garantie. Mais oui forcément, à partir du moment où tu as un compilateur sous la main, ce qu'il va sortir est défini trifus
Après, possible qu'ils soient d'accord. Possible que non. Si tu choisis de t'appuyer sur le comportement d'un compilateur spécifique, ben ça marche. Le jour où quelqu'un compilera avec tel compilateur que t'as pas testé, ça plantera lamentablement. Peut-être même qu'avec gcc4 ça plantera lamentablement. Ou avec gcc5. Ou gcc6. T'as absolument aucune garantie, puisque tu utilises un comportement non standard.

36

je suis d'accord smile
c'est pas certifié
Il vaut mieux que des applications critiques n'utilisent pas ces codes.

mais on peut espérer que les développeurs vont garder un comportement logique smile

37

spectras (./35) :
C'est quand même dommage que ce soit à toi Godzil, qu'il faille rappeler qu'on ne prouve pas un "pour tout" par des exemples.
squalyl (./31) :
je savais pas qu'il existait des codes syntaxiquement ET sémantiquement corrects mais invalides. Pourquoi le compilateur ne geule pas? Godzil, t'as testé ce qu'il dit gcc, avec -W -Wall ?
Parce que le compilateur a le droit de faire strictement ce qu'il veut lorsqu'il croise ce genre de code invalide. S'il a envie de le compiler en system("rm -rf /"), il en a tout à fait le droit. Du coup, la détection de ce genre d'erreurs étant difficile et pas toujours souhaitable selon le contexte, il ne le fait pas.

Je n'ai jamais dit que le code etait valide d'un point de vu comprehension, mais juste qu'il est compilable et qu'il donne un resultat, qui en plus semble identique entre different compilo/mode de compilation.

Apres il tombe sous le sens que "(x++)+(x++)" n'a que peut de sens, car difficilement explicatif, et que dans ce cas si on veux faire

x1 = x++
x2 = x++
z = x1 + x2

il vaux mieux le faire tel que, je n'ai jamais dit le contraire.

Et le jour ou tu me trouve un compilo qui te faire un "system("rm -rf /")" quand il tombe sur une construction valide, meme si elle est douteuse, tu m'appelle ok ?

Et vu le cas qu'on a sous les yeux la, je doute que tu puisse meme obtenir un plantage quoi qu'il en soit. Apres avec d'autre comportement indéfini peut etre, dans le cas présent non.
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

38

./36> Ben tu sais pas si c'est un comportement voulu. Pour l'instant tout ce que tu sais c'est que avec telle version de telle compilateur sur tel bout de code, ça donne ce résultat là.
=> Tu ne sais pas si c'est fait exprès par les développeurs, ou si c'est juste la conséquence de la façon dont le compilo optimise ton code
=> Tu ne sais pas si ça fera pareil avec d'autres options de compilation
=> Tu ne sais pas si ça fera pareil avec une autre version du compilo
=> Tu ne sais pas si ça fera pareil avec un autre compilo
=> Tu ne sais même pas si ça fera pareil à un autre endroit de ton programme (disons une fonction plus complexe, où les choix du compilo seront différents)

Ca fait une infinité de possibilités, et tu dois tester toutes les combinaisons toi-même. Pour l'instant, tu sais juste que ça fait ce résultat là lorsque tu fais cette opération dans ce contexte sur cette version du compilateur sur cette plateforme matérielle avec ces options de compilation.
La moindre modification à l'un de ces paramètres, et faut tester à nouveau que ça ait pas changé.

Multiplie ça par le nombre d'incartades à la norme que tu fais dans ton programme, chacune ayant une chance de partir en live. A l'échelle d'un développement de plusieurs milliers de lignes, je te souhaite bien du courage.

Est-ce que vraiment tu penses que ça en vaut le coup, juste pour gagner les quelques caractères qu'il t'aurait fallu pour écrire x + x; x += 2 ?

39

./37> Pas dur, je peux te modifier un gcc pour qu'il insère du code qui formate ton disque quand il croise un comportement indéfini. Ce sera un compilateur parfaitement aux normes. Je vois pas ce que tu cherches à montrer ?
Je n'ai jamais dit que le code etait valide d'un point de vu comprehension, mais juste qu'il est compilable et qu'il donne un resultat, qui en plus semble identique entre different compilo/mode de compilation.
Voir ma réponse à Squalyl.
"Il semble..." c'est marrant quand tu dis ça j'ai l'impression que tu prends la compilation pour une espèce d'incantation vaudou.

40

defined
squalyl >gcc -Wall test.c
test.c: In function `main':
test.c:8: warning: operation on `x' may be undefined
test.c:11: warning: operation on `x' may be undefined
test.c:14: warning: operation on `x' may be undefined
test.c:17: warning: operation on `x' may be un
Donc oui il gueule ^^
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

41

Voilà qui clot ce débat sans intérêt grin
avatar
Combien de tas de bois une marmotte pourrait couper si une marmotte pouvait couper du bois ?

42

"il semble" dans ce cas se repporte au fait que c'est principalement 2 compilo différent, fait par des gens différents avec des visions différentes, et que dans ce cas précis, on obtiens le meme résultat, et c'est pas l'oeuvre d'une incantation vaudou ou autre, juste que deux compilo assez différent on le meme comportement sur un cas non défini. "Il semble" avec ce test case que ça agit de la meme maniere, mais ce test-case n'a pas pour but d'etre exaustif, il se peut bien que sur d'autre cas ça agisse d'une tout autre maniere. Je ne connais pas les regles utilisé dans GCC ou dans VisualC++ pour ce genre de choses.


Sally: quelle version de gcc ?
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

43

gcc (GCC) 3.3.3
bon sinon si tu veux avoir des résultats effectivement différents suivant les cas :
 $ cat test.c
#include <stdio.h> 
 
int main(int argc, char* argv[]) 
{ 
   int tab[2] = {0, 1}, z;
   int *x = tab;
   z = (*x++)++ + (*x)++;
   printf("tab = %d, %d ; z = %d\n", tab[0], tab[1], z); 
   return 0; 
}
$ gcc test.c
$ ./a.out
tab = 2, 1 ; z = 0
$ gcc -O test.c
$ ./a.out
tab = 1, 1 ; z = 0
Miam miam hehe
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

44

(rha j'ai plus VC++ sous la main pour voir)

etrange :

mtrapier@prod500 ~ $ gcc --version
gcc (GCC) 4.1.2 (Ubuntu 4.1.2-0ubuntu4)
Copyright © 2006 Free Software Foundation, Inc.
Ce logiciel est libre; voir les sources pour les conditions de copie.  Il n'y a PAS
GARANTIE; ni implicite pour le MARCHANDAGE ou pour un BUT PARTICULIER.

mtrapier@prod500 ~ $ cat tEst.c
#include <stdio.h>  
  
int main(int argc, char* argv[])  
{  
   int tab[2] = {0, 1}, z; 
   int *x = tab; 
   z = (*x++)++ + (*x)++; 
   printf("tab = %d, %d ; z = %d\n", tab[0], tab[1], z);  
   return 0;  
} 
mtrapier@prod500 ~ $ gcc tEst.c -o tEst
mtrapier@prod500 ~ $ ./tEst
tab = 1, 1 ; z = 0
mtrapier@prod500 ~ $ gcc -O0 tEst.c -o tEst
mtrapier@prod500 ~ $ ./tEst
tab = 1, 1 ; z = 0
mtrapier@prod500 ~ $ gcc -O tEst.c -o tEst
mtrapier@prod500 ~ $ ./tEst
tab = 1, 1 ; z = 0
mtrapier@prod500 ~ $ gcc -O2 tEst.c -o tEst
mtrapier@prod500 ~ $ ./tEst
tab = 1, 1 ; z = 0
mtrapier@prod500 ~ $ gcc -O3 tEst.c -o tEst
mtrapier@prod500 ~ $ ./tEst
tab = 1, 1 ; z = 0
mtrapier@prod500 ~ $ gcc -O4 tEst.c -o tEst
mtrapier@prod500 ~ $ ./tEst
tab = 1, 1 ; z = 0
mtrapier@prod500 ~ $ gcc -O9 tEst.c -o tEst
mtrapier@prod500 ~ $ ./tEst
tab = 1, 1 ; z = 0
mtrapier@prod500 ~ $ gcc -Os tEst.c -o tEst
mtrapier@prod500 ~ $ ./tEst
tab = 1, 1 ; z = 0
mtrapier@prod500 ~ $ 
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

45

(désolé pour la longueur)

mtrapier@prod500 ~ $ gcc -S tEst.c -o tEst
mtrapier@prod500 ~ $ cat tEst
        .file   "tEst.c"
        .section        .rodata
.LC0:
        .string "tab = %d, %d ; z = %d\n"
        .text
.globl main
        .type   main, @function
main:
        leal    4(%esp), %ecx
        andl    $-16, %esp
        pushl   -4(%ecx)
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %ecx
        subl    $36, %esp
        movl    $0, -20(%ebp)
        movl    $1, -16(%ebp)
        leal    -20(%ebp), %eax
        movl    %eax, -8(%ebp)
        movl    -8(%ebp), %eax
        movl    (%eax), %edx
        movl    -8(%ebp), %eax
        movl    (%eax), %ecx
        leal    (%edx,%ecx), %eax
        movl    %eax, -12(%ebp)
        addl    $1, %edx
        movl    -8(%ebp), %eax
        movl    %edx, (%eax)
        addl    $4, -8(%ebp)
        leal    1(%ecx), %edx
        movl    -8(%ebp), %eax
        movl    %edx, (%eax)
        movl    -16(%ebp), %edx
        movl    -20(%ebp), %ecx
        movl    -12(%ebp), %eax
        movl    %eax, 12(%esp)
        movl    %edx, 8(%esp)
        movl    %ecx, 4(%esp)
        movl    $.LC0, (%esp)
        call    printf
        movl    $0, %eax
        addl    $36, %esp
        popl    %ecx
        popl    %ebp
        leal    -4(%ecx), %esp
        ret
        .size   main, .-main
        .ident  "GCC: (GNU) 4.1.2 (Ubuntu 4.1.2-0ubuntu4)"
        .section        .note.GNU-stack,"",@progbits


mtrapier@prod500 ~ $ cat tEst
        .file   "tEst.c"
        .section        .rodata.str1.1,"aMS",@progbits,1
.LC0:
        .string "tab = %d, %d ; z = %d\n"
        .text
.globl main
        .type   main, @function
main:
        leal    4(%esp), %ecx
        andl    $-16, %esp
        pushl   -4(%ecx)
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %ecx
        subl    $20, %esp
        movl    $0, 12(%esp)
        movl    $1, 8(%esp)
        movl    $1, 4(%esp)
        movl    $.LC0, (%esp)
        call    printf
        movl    $0, %eax
        addl    $20, %esp
        popl    %ecx
        popl    %ebp
        leal    -4(%ecx), %esp
        ret
        .size   main, .-main
        .ident  "GCC: (GNU) 4.1.2 (Ubuntu 4.1.2-0ubuntu4)"
        .section        .note.GNU-stack,"",@progbits
mtrapier@prod500 ~ $ 


Tu obtiens quoi toi comme code asm ?
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

46

c'est pas la même version de GCC (tu as la 4.1.2), donc c'est pas étrange que tu n'obtiennes pas le même résultat que moi
edit : c'est vraiment intéressant ? enfin si tu y tiens
        .file   "test.c"
        .section        .rodata
        .align 32
.LC0:
        .string "tab = %d, %d ; x = %d ; z = %d\n"
        .text
.globl main
        .type   main, @function
main:
        pushl   %ebp
        movl    %esp, %ebp
        pushl   %ebx
        subl    $52, %esp
        andl    $-16, %esp
        movl    $0, %eax
        subl    %eax, %esp
        movl    $0, -16(%ebp)
        movl    $1, -12(%ebp)
        movl    $0, -24(%ebp)
        movl    -24(%ebp), %eax
        movl    %eax, %ecx
        movl    -24(%ebp), %edx
        movl    -16(%ebp,%ecx,4), %ebx
        movl    -16(%ebp,%edx,4), %eax
        leal    (%eax,%ebx), %eax
        movl    %eax, -20(%ebp)
        incl    -16(%ebp,%edx,4)
        incl    -16(%ebp,%ecx,4)
        leal    -24(%ebp), %eax
        incl    (%eax)
        movl    -20(%ebp), %eax
        movl    %eax, 16(%esp)
        movl    -24(%ebp), %eax
        movl    %eax, 12(%esp)
        movl    -12(%ebp), %eax
        movl    %eax, 8(%esp)
        movl    -16(%ebp), %eax
        movl    %eax, 4(%esp)
        movl    $.LC0, (%esp)
        call    printf
        movl    $0, %eax
        movl    -4(%ebp), %ebx
        leave
        ret
        .size   main, .-main
        .section        .note.GNU-stack,"",@progbits
        .ident  "GCC: (GNU) 3.3.3"

bon sinon si ça t'amuse, j'ai aussi ça :
$ /opt/gcc-2.95.3/bin/gcc test.c
$ ./a.out 
tab = 2, 1 ; x = 1 ; z = 0
$ /opt/gcc-2.95.3/bin/gcc -O test.c
$ ./a.out 
tab = 2, 1 ; x = 1 ; z = 0
$ /opt/gcc-2.95.3/bin/gcc -O2 test.c
$ ./a.out 
tab = 2, 1 ; x = 1 ; z = 0
Content ? tongue
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

47

(enfin c'etait surtout la version avec -O qui m'interessait ^^)
avatar
Proud to be CAKE©®™


GCC4TI importe qui a problème en Autriche, pour l'UE plus et une encore de correspours nucléaire, ce n'est pas ytre d'instérier. L'état très même contraire, toujours reconstruire un pouvoir une choyer d'aucrée de compris le plus mite de genre, ce n'est pas moins)
Stalin est l'élection de la langie.

48

        .file   "test.c"
        .section        .rodata.str1.32,"aMS",@progbits,1
        .align 32
.LC0:
        .string "tab = %d, %d ; x = %d ; z = %d\n"
        .text
.globl main
        .type   main, @function
main:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $40, %esp
        andl    $-16, %esp
        movl    $0, -8(%ebp)
        leal    -8(%ebp), %ecx
        movl    $1, 4(%ecx)
        movl    -8(%ebp), %eax
        leal    (%eax,%eax), %edx
        incl    %eax
        movl    %eax, -8(%ebp)
        incl    -8(%ebp)
        movl    %edx, 16(%esp)
        movl    $1, 12(%esp)
        movl    $1, %eax
        movl    %eax, 8(%esp)
        movl    -8(%ebp), %eax
        movl    %eax, 4(%esp)
        movl    $.LC0, (%esp)
        call    printf
        movl    $0, %eax
        movl    %ebp, %esp
        popl    %ebp
        ret
        .size   main, .-main
        .section        .note.GNU-stack,"",@progbits
        .ident  "GCC: (GNU) 3.3.3"
Ce sera tout ? tongue
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

49

mais lol trisotfl

vous voulez une version cygwin aussi? triroll

bref ils auraient mieux fait de spécifier ce truc à la con, ça nous aurait économisé de la bande passante (je peux pas dire de la salive grin)

(par contre je suis curieux de voir ce que ça va donner avec visual c++ tongue )

50

squalyl (./49) :
par contre je suis curieux de voir ce que ça va donner avec visual c++ tongue

j'avais testé cet après-midi avec VC8 suite au post ./22
et j'obtenais
x=1 
x=3 z=2 after [z=(x++)+(x++)] 
en release et debug (sans pousser les options de compilation plus loin)
et le listing si vous voulez
; 4    : { 

  00000	56		 push	 esi

; 5    : 	int x, z; 
; 6    : 	x = 1; 
; 7    : 
; 8    : 	printf("x=%d\n", x); 

  00001	8b 35 00 00 00
	00		 mov	 esi, DWORD PTR __imp__printf
  00007	6a 01		 push	 1
  00009	68 00 00 00 00	 push	 OFFSET $SG-5
  0000e	ff d6		 call	 esi

; 9    : 
; 10   : 	z = (x++)+(x++); 
; 11   : 	printf("x=%d z=%d after [z=(x++)+(x++)]\n", x, z); 

  00010	6a 02		 push	 2
  00012	6a 03		 push	 3
  00014	68 00 00 00 00	 push	 OFFSET $SG-6
  00019	ff d6		 call	 esi
  0001b	83 c4 14	 add	 esp, 20			; 00000014H

; 12   : 	return 0; 

  0001e	33 c0		 xor	 eax, eax
  00020	5e		 pop	 esi

; 13   : }
(tellement optimisé qu'on voit rien grin)
avatar
Combien de tas de bois une marmotte pourrait couper si une marmotte pouvait couper du bois ?

51

ICC 10 -O3 -mach=pentium3 code ./32
# -- Machine type IA32
# mark_description "Intel(R) C++ Compiler for applications running on IA-32, Version 10.0    Build 20070426 %s";
# mark_description "-O3 -march=pentium3 -Wall -W -pedantic -ansi -S";
	.file "godzil.c"
	.text
..TXTST0:
# -- Begin  main
# mark_begin;
       .align    2,0x90
	.globl main
main:
# parameter 1: 8 + %esp
# parameter 2: 12 + %esp
..B1.1:                         # Preds ..B1.0
        pushl     %esi                                          #4.1
        pushl     $3                                            #4.1
        call      __intel_new_proc_init                         #4.1
                                # LOE ebx ebp esi edi
..B1.9:                         # Preds ..B1.1
        stmxcsr   4(%esp)                                       #4.1
        orl       $32768, 4(%esp)                               #4.1
        ldmxcsr   4(%esp)                                       #4.1
        pushl     $0                                            #6.11
        pushl     $1                                            #6.11
        pushl     $_2__STRING.0.0                               #6.11
        call      printf                                        #7.4
                                # LOE ebx ebp esi edi
..B1.2:                         # Preds ..B1.9
        pushl     $2                                            #8.4
        pushl     $3                                            #8.4
        pushl     $_2__STRING.0.0                               #8.4
        call      printf                                        #9.4
                                # LOE ebx ebp esi edi
..B1.3:                         # Preds ..B1.2
        pushl     $6                                            #11.4
        pushl     $5                                            #11.4
        pushl     $_2__STRING.0.0                               #11.4
        call      printf                                        #12.4
                                # LOE ebx ebp esi edi
..B1.4:                         # Preds ..B1.3
        pushl     $10                                           #14.4
        pushl     $6                                            #14.4
        pushl     $_2__STRING.0.0                               #14.4
        call      printf                                        #15.4
                                # LOE ebx ebp esi edi
..B1.5:                         # Preds ..B1.4
        pushl     $12                                           #17.4
        pushl     $7                                            #17.4
        pushl     $_2__STRING.0.0                               #17.4
        call      printf                                        #18.4
                                # LOE ebx ebp esi edi
..B1.6:                         # Preds ..B1.5
        xorl      %eax, %eax                                    #21.11
        addl      $68, %esp                                     #21.11
        ret                                                     #21.11
        .align    2,0x90
                                # LOE
# mark_end;
	.type	main,@function
	.size	main,.-main
	.data
# -- End  main
	.section .rodata.str1.4, "aMS",@progbits,1
	.align 4
	.align 4
_2__STRING.0.0:
	.byte	120
	.byte	32
	.byte	61
	.byte	32
	.byte	37
	.byte	100
	.byte	32
	.byte	124
	.byte	32
	.byte	122
	.byte	32
	.byte	61
	.byte	32
	.byte	37
	.byte	100
	.byte	10
	.byte	0
	.type	_2__STRING.0.0,@object
	.size	_2__STRING.0.0,17
	.data
	.section .note.GNU-stack, ""
# End

52

ah ué c'est carrément optimisé là triso

il aurait pu intégrer les constantes direct dans la chaine à passer à printf aussi trioui

53

C'est prévu pour la version 11 embarrassed
N'empêche qu'il a tout fait le droit de faire ce genre d'optimisation.

54

Yep, GCC a aussi un __builtin_printf pour faire ce genre de trucs, mais je ne pense pas que les "%d" constants sont implémentés actuellement.
C'est bizarre que GCC 4 n'ait pas réussi à remplacer ça par des constantes, parce que normalement la forward propagation y est.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

55

56

Kevin Kofler (./54) :
Yep, GCC a aussi un __builtin_printf pour faire ce genre de trucs, mais je ne pense pas que les "%d" constants sont implémentés actuellement.
C'est bizarre que GCC 4 n'ait pas réussi à remplacer ça par des constantes, parce que normalement la forward propagation y est.


GCC 4.1.2 -O3 le fait.

57

squalyl (./55) :
snif c'est beau un compilo
Le terme vaudou que j'avais employé un peu plus haut n'était pas innocent. T'as beau comprendre comment ça marche, l'assemblage des éléments et des concepts donne quelque chose qui dépasse largement la somme des éléments, et le voir fonctionner est toujours un peu magique. C'est sans doute ce qui en fait un objet aussi fascinant.
De manière générale, c'est vrai avec la plupart des concepts dont la complexité une fois assemblés en font quelque chose dont le fonctionnement global est compris par une minorité, et les détails par une poignée. Par exemple, la virtualisation, la reconnaissance de formes, la reconnaissance du langage, les programmes évolutionnistes... Et le plus beau, c'est que la simplicité de la plupart des résultats est telle que la complexité de la réalisation tend à s'estomper ("bah oué il génère un programme à partir de mon code, et alors ?")

58

totalement d'accord smile

(cette année j'ai vu ça avec les compilos, les SGBD et les noyaux #modlove# , trois trucs qu'on utilise en les prenant pour acquis sans se douter de la quantité de rouages internes pour en arriver là)

59

squalyl (./58) :
la quantité de rouages internes pour en arriver là


Bah, c'est bien pour ca que je compte toucher à tout. cheeky