A question bete, reponse idiote

on m’a (moktar pour ne pas le citer :pleure: ) souvent pauser une question sur un petit problem de C :
Quel doit etre le resultat du code suivant :

if( C>C++ )
printf("C > C++
") ;

doit il afficher ou pas ?

Comme j’aime pas qu’on m’escagasse (et ce a plusieur reprise, n’s’pas m’sieur moktar :P), j’ai donc degainer ma panoplie de compilo c : visualC ^, CodeWarrior 7, djgpp gcc, et cygwin gcc.
et je leur est soumis le programme suivant :

[b]
int main(int argc, char* argv[])
{
int C = 0;

if( C>C++ )
printf("C > C++
") ;

return 0;
}
[/b]

resultat :

VC 6 : n’affiche jamais la chaine.
CW7 : affiche toujours la chaine.
djgpp gcc : affiche toujours la chaine.
cygwin gcc : affiche toujours la chaine.

donc l’idee serait que, d’apres 75% des compilos C++ est evaluer avant d’effectuer la comparaison, ce qui est etonnant car mettre « ++ » apres C signifie au compilateur : resout d’abord l’expression, puit increment C de 1.

mais alors ? pourquoi ?

hey bien parce que d’apres le standard ANSI, et la plus part des commentateurs et autres gourou : une expression contenant en meme temps C et C++ tel que : C>C++, C * C++ et autres est consideree comme non specifie voir non definie. Donc personne ne sait, donc chaque compilateur a le droit de faire ce qu’il veux.
(je tiens a signaler d’ailleurs que pclint (precompilateur pour programmeur pointilleux) couine comme un goret a la simple vue de la ligne en question… )
(et que CodeWarrior n’optimize pas tres bien le code en question vu qu’il effectue le test meme quand il sait que rien ne va changer…)

voir http://www.eskimo.com/~scs/C-faq/q3.1.html

si joins mes notes et les resultat en assenbleur x86 compilo par compilo (sans alt+255, parce que j’ai la fleme :smiley: )
Note :

  • quand j’ecris « C » je veux dire dans la memoire
  • quand j’ecris « &C » je veux dire l’adresse en memoire de C
  • le plus gros du code assembleur est supprimer pour garder la partie interessante.

VisualC 6:
toujours faux.

debug :
mov eax,dword ptr [ebp-4] ; eax = C
mov ecx,dword ptr [ebp-4] ; ecx = C
mov edx,dword ptr [ebp-4] ; edx = C
add edx,1 ; edx++ → edx = c+1
mov dword ptr [ebp-4],edx ; C = edx
cmp eax,ecx ; Compare eax et ecx

release :
comme le compilo considere le test comme toujours faux : il sort sans
effectuer le test en question.

CodeWarrior 7:
toujours vrais.

debug:
mov edx,dword ptr [ebp-4] ; edx = C
inc dword ptr [ebp-4] ; C++
cmp dword ptr [ebp-4],edx ; Compare edx et C

release:
xor ebx,ebx ; ebx = 0
[…]
mov eax,ebx ; eax = ebx
inc ebx ; ebx++ → ebx = 1
cmp ebx,eax ; Compare eax et ebx.

djgpp gcc 3.1:
toujours vrais
debug :

mov edx, DWORD PTR [ebp-4] ; edx = C
lea eax, [ebp-4] ; eax = &C
inc DWORD PTR [eax] ; C++
cmp edx, DWORD PTR [ebp-4] ; Compare C et edx

release :
comme le compilo considere le test comme toujours vrais : il sort sans
effectuer le test en question et affiche le message.

cygwin gcc 2.95.3-5 :
toujours vrais.
debug :
movl -4(%ebp),%eax ; eax = C
incl -4(%ebp) ; C++
cmpl %eax,-4(%ebp) ; Compare C et eax

traduction code type masm/tasm :
mov eax,dword ptr [ebp-4]
inc dword ptr [ebp-4]
cmp dword ptr [ebp-4],eax

release:
comme le compilo considere le test comme toujours vrais : il sort sans
effectuer le test en question et affiche le message.

[quote]Ouais cool, sympa ça sûrement[/quote]c vrais que c assez sympa, et puis ont a access a toutes les dernieres platformes et tout :slight_smile:

[quote]Les développements moteurs 3d multi-plateformes regroupes combien de personnes (selon ton XP) ?[/quote]par equipe : entre 5 et 150 en contant le suport, ca depends des boites, des moteurs et du reste :).
Maintenant pour le middleware (les moteur a acheter) : t’as les deux stars : qIII et UT, le leader RenderWare, le deuxieme Netimmerse, puis d’autres, genre QubeSoft (voir news), alchemy, lythek et puis d’autres, encore plein.

[quote]Tu fais du VRAI code standard C/C++ donc juste une recompile est nécessaire lorsque tu portes un moteur sur une autre plateforme ? ou bien c’est illusoire, selon ton XP toujours, bien sûr.[/quote]la dessus y a 2 ecoles :
la premiere c’est meme headers, meme code, tu recompiles, ca marche. c lent.
la deuxieme c’est meme headers, meme code de bases, et version super optimizee par plateforme la ou tu a moyen de le faire, ca marche. mieux. a mon avis :devil2:
Mais c clair que pour le code commun tu te traines en moyenne 4/5 compilo par plateforme, et une bonne moyenne de 5/6 plateforme, donc si ton code est pas super standard, tu pleures :calin: (et puis t’oublie le c++ parce que dans la plus part des cas deux fichier c++ compiles avec deux compilo different : t’es zobi au link :drink: )

[quote]si on fait
if (c > c++)

on incrémente 0, non ?[/quote] :casstet:
:casstet:
:casstet:
oui mais non,
:casstet:
tu incremente LA VARIABLE C, qui est peut etre egale a 19874 si ca te chantes, donc tu incremente pas « zero » tu incrementes une variable, rotudju :devil2:.

donc on reprends :
C++ : oui
0++ : non

le « ++ » c un truc pour programmeur fleimard (et comme me disait ma mere : « Un bon programmeur, c’est un programmeur fleimard, et laisse moi te dire que quand on vois ta chambre, tu dois etre un TRES TRES TRES bon programmeur ») : qui remplace le plus classique :

variable = variable +1;

donc si tu fait
C++
ca te donne :
C = C + 1;
et si tu fait
0(comme dans zero)++
ca te donne :
0 = 0 +1;
et ca c’est vraiment n’importe quoi :pleure:

[Edité le 17/7/2002 par c0unt0]

je trouve pas que j’ai vraiment perdu…

si on incrémente le résultat d’un test, bah ça fait de la mer**

Voilà mon raisonnement.

si on fait
if (c > c++)

on incrémente 0, non ?

Ouais cool, sympa ça sûrement :P.

Les développements moteurs 3d multi-plateformes regroupes combien de personnes (selon ton XP) ?
Tu fais du VRAI code standard C/C++ donc juste une recompile est nécessaire lorsque tu portes un moteur sur une autre plateforme ? ou bien c’est illusoire, selon ton XP toujours, bien sûr.

Merci mon petit Moktar :slight_smile: mais je suis encore un jeunot dans le domaine :smiley:

En gros nighthunter, l’application concrète de ce problème qui a l’air d’être de la pure bran*$$, c’est entre autre la recherche de bugs liés aux effets de bord :P, ou plutôt, une meilleure connaissance de ton compilo chéri. En lisant les specs, tu te rends compte que ton compilo est libre dans pas mal de situations, donc si tu aimes optimiser ton code, ça te sert pas mal. Mais avant toute chose je te renvoie à une citation du K&R, la bible du C, comme l’a souligné Moktar. C’est simple, c’est ma signature depuis aujourd’hui :wink: :wink: :wink:

hurlosaure> rhooo t’as encore perdu :wink:

[Edité le 17/7/2002 par xentyr]

hurlosaure : non ca marche pas : dans tout les cas c’est indefinie, tu ne pourra jamais faire du code portable si tu utilise ce genre de truc, c juste un truc a ne pas faire, jamais, c mal, c en dehors de la voie du code simple sain.

[quote]hi hi hi nighthunter, c’est juste pour se br*$@…
Je crois que c’est parti d’un ancien POST où cOuntO mettait le compilo GNU comme la référence… alors j’ai proposé quelques exemples que je considérais comme des mauvais comportements de ce compilo, juste comme ça et là zou, cOuntO en remet une couche (ça me plait bien d’ailleurs).[/quote]oui, c vrais, c juste un grand debat theologique, et pis il m’agacait le moktar a me narguer, et quand on m’agace : bah c reflex : j’agace aussi :P,
Et c pas pire que les debats de quinze jour sur le dernier Michael Jackson, ou faire les mots croise, ou savoir si WIII ca rulezz vraiment a mort :slight_smile: c juste du sport pour les meninges, a l’arrive on y gagne tous un truc : on apprends des trucs, et on rigole :wink:

et pour ma part je devellope en c/c++/assembleur sur du moteur 3d multi platform (PC/PS2 principalement, et un peu de X-Box/gamecube).

comme quoi y a plus que dans le graphisme et les telecoms qu’on trouve des vrais programmeur ;):);):slight_smile:

P.S. : 0++ marche pas : c une constante, ca s’incremente pas une constante, c comme vouloir refaire la pate d’une quiche surgelee ;):slight_smile:

[Edité le 17/7/2002 par c0unt0]

if((c > c) ++)
!=
if((c > (c++))
on est d’accord.

je me demande si 0++; passe
rien n’est là pour stocker cette valeur, donc… ça fait schtrüntz, non ?

hi hi hi nighthunter, c’est juste pour se br*$@… :cool:
Je crois que c’est parti d’un ancien POST où cOuntO mettait le compilo GNU comme la référence… alors j’ai proposé quelques exemples que je considérais comme des mauvais comportements de ce compilo, juste comme ça :music: et là zou, cOuntO en remet une couche (ça me plait bien d’ailleurs).

Nighty, je te conseille le Kernighan et Ritchie comme bouquin de référence pour le C (encore qu’il serait préférable d’avoir la norme :)).
Pour le C++ un bouquin de Bjarne Stroustrup.

Ce sont des docs de références, donc pas très adaptés à l’apprentissage…

Je crois que universal_tonton a déjà cité deux autres bouquins dans un précédent POST.

Sinon, je fais du développement logiciel (C et C++) et plutôt orienté télécom (encore que récemment, non). (merci pour ta flatterie, tu as oublié Xentyr :))

hurlosaure : Non c’est pas ça, relit les POSTs.

[Edité le 17/7/2002 par Moktar]

bon je crois avoir compris le probleme (je ne programme pas sauf a l’iut, mais ca compte pas vu le niveau :music: )

j’aimerais savoir s’il y a une aplication concrete de se probleme? ou si c’est juste pour soulevé le probleme.

enfin c0unt0 et moktar c’est quoi votre boulot vous avez l’air de maitriser comme des betes en programmation.

derniere chose connaisez vous un bouquin pour aprendre a faire du C qui demarre de debutant a avancé?

edit: nombre de messages=666 the number of the beast :slight_smile:

[Edité le 17/7/2002 par nighthunter]

:open_mouth: Je me suis bien fait allumé la tête…

Pour vous dire le fond de ma pensée… J’avais surtout l’impression que vous vous branliez grave le jonc pour un problème tout petit petit.

et en rajoutant des parenthèses ? ç suffit pas ?

if((c > c) ++)
!=
if((c > (c++))

non ?

je me suis un peu emballé, sorry :music:

[Edité le 17/7/2002 par hurlosaure]

[quote]quelqu’un dit au dessus:

“le problème se situe autour de la condition : if( C>C++) et de l’utilisation des 2 caractères C et C++ dans une meme instruction”

bah justement c’est COMPLèTEMENT DéBILE comme problème.[/quote]Oui c’est moi. Et c’est PAS débile. C’est le genre de truc qui te fait perdre du temps a la compilation, a savoir les mots “non-spécifié” ou “interdit” pour les variables. (ca m’est arrivé en Tp, galerer pdt 1h a la compil jusqu’a ce qu’on me dise que ce nom de variable ne peut pas etre utiliser car réservé par le langage…). Alors think un poil au probleme avant de nous sortir du “0>1 mais c’est evident euuuh”…

[quote]C’était une érection de fatigue[/quote]Mouarf :oops:

[Edité le 17/7/2002 par GluP]

Tu as raison.
C’était une érection de fatigue :oops:

[Edité le 17/7/2002 par Moktar]

euh, Moktar, à part la grosse boulette :oops:, y’a juste un autre problème, c’est que si je me rappelle bien, les arguments d’une fonction ne sont pas gérés comme une suite d’expressions séparées par une virgule donc ton érection s’est révélée un peu vite car ça ne s’applique pas pour c0unt0 :oops:

[Edité le 17/7/2002 par xentyr]

D’accord, en plus j’ai laissé passé une boulette (oui il n’y a qu’un seul paramètre), mais ça ne renie pas le contenu du précédent POST :oops:

Bien sûr, il ne s’agit pas d’écrire du code dégueux comme ça hein, cela va sans dire, mais ça va mieux en le disant. :oops:

c vrais mais

[quote]printf("%d %d
", (++n, power(2,n)) ) ;[/quote]ton deuxieme « %d », il va afficher dans le vent, vu que la nouvelle parenthese fait que (++n, power(2,n)) est un seul parametre, donc pour faire propre il vaut mieux (comme ils le precise dans le K&R) faire :

n++;
printf("%d %d
", n, power(2,n) ) ;

en tout cas : t’es sur de pas te chier dessus en faisant ca :slight_smile:
et c’est simple et sain :slight_smile:

Ca y est je bande. :stuck_out_tongue:

Heu pouf pouf couché. J’adore les trucs un peu couillu :). Aller zou, pour relancer un peu la polémique (juste pour le plaisir), le document que cite cOuntO n’est pas la norme. C’est la référence OK, j’utilise la même ;), mais j’ai également une version du K&R révision ANSI aux éditions Masson et j’ai appris quelque chose aujourd’hui, la référence de la norme c’est : X3.159-1989. Lorsqu’on fait du protocole (X.25, LAPB-B, GSM, GPRS, …) on a toujours LA NORME sous la main, et c’est vraiment bizarre qu’en langage "on " ne conserve pas ce principe… je me surprends moi-même…

Mon manuel précise bien que c’est une interprétation de la norme. Pour illustrer ces propos j’ouvre mon manuel chapitre A7.18 L’opérateur virgule :

« Deux expressions séparées par une virgule s’évaluent de gauche à droite et la valeur de gauche est perdue …/… » c’est pour apporter la contradiction à l’affirmation précédente de cOuntO :slight_smile: cf le printf.

il y a même un exemple dans MA :wink: référence :

"f(a, (t=3, t+2), c)

le second paramètre vaut 5"

Je pense que dans l’exemple de cOuntO et si je m’appuie sur mon document il faudrait écrire :

printf("%d %d
", (++n, power(2,n)) ) ;

pour définir l’expression…

Ma contribution.

Merci pour la confirmation

[quote]is left to the discretion of the compiler…[/quote]mmmh j’aime :):slight_smile: :wink:

[quote]if you don’t know how they are done on various machines, you won’t be tempted to take advantage of a particular implementation.[/quote]D’où l’intérêt de faire du bas niveau aussi hehe ;)) comme ça on sait ce qu’on fait :wink:
Vive l’archi !!!

Bahh bien, le lien, j’en connais beaucoup à qui je vais le forwarder cette après-m’ :stuck_out_tongue:

Hop à la graille :slight_smile:

Ps: Pour les allergiques de la langue de Shapespeare, ben vraiment désolé pour vous :frowning:
Il vous reste quand même WinDev :stuck_out_tongue: A&icric;e pas taper !!! :cool:

[Edité le 17/7/2002 par xentyr]

dans le Kernighan and Ritchie ( in The C programming language, Brian W. Kernighan et Dennis M. Ritchie, aux editions Prentice Hall software Series , et qui dois exister en francais, et que je recommande chaudement a tout les programmeurs c (le C c eux :slight_smile: ) ), seconde edition, section 2.12 :
ils disent :
"
Function calls, nested assignment statements, and increment and decrement operators cause « side-effects »-some variable is changed as a by-product of the evaluation of an expression. In any expression involving side effects, there can be subtle dependencies on the order in which variables taking part in the expression are pdated. One unhappy situation is typified by the statement :
a[ i ] = i++;
The question is whether the subscript is the old value of i or the new. Compilers can interpret this in different ways, and generate different answers depending on their interpretation. The standard intentionally leaves most such matters unspecified (c pour ca que c pas dans l’ANSI :slight_smile: ). When side effects (assignement of variables) take place within an expression is left to the discretion of the compiler, since the best order depends strongly on machine architecture. (The standard does specify that all side effects on argument take effect before a function is called, but that would not help in the call to printf above (le code en question est : printf("%d %d
« , ++n, power(2,n)); ).
The moral is that writing code that depends on order of evaluation is a bad programming practice in any language. Naturally, it is necessary to know what things to avoid, but if you don’t know how they are done on various machines, you won’t be tempted to take advantage of a particular implementation. »

mais je suis pas d’accords avec la dernier ligne : il faut savoir savoir et savoir ne pas utiliser ses connaissances :wink:

et pour le fun : http://www.plethora.net/~seebs/faqs/c-iaq.html#section-3

[Edité le 17/7/2002 par c0unt0]

[Edité le 17/7/2002 par c0unt0]

Pour ma part je retire ce que j’ai dit !
le test ( C < C++) étant vraiment plus complexe quand on y réfléchi 2 sec … (oui mon premier post était en mode CERVEAU[OFF] )

Hurlausore > dans le fameux test (C < C++) les premier C est aussi susceptible d’être incrémenté…

nan je l’ai suprimer le message : Ct grosses conneries inside, t’avais raison : c tout indefinie, tout, tout le temps : la je cherche le K&R, pour verifier :slight_smile: