- Posté le 21/11/2009 à 11:17 Membre depuis le 18/06/2001, 30160 messages
Même sur PC, Kevin est pour l'optimisation taille. grin
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 21/11/2009 à 11:26 Membre depuis le 28/08/2003, 8213 messages
Chose que je trouve assez absurde. Ce qui compte, c’est la taille de l’exécutable généré et la lisibilité du code.
avatar « Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »
- Posté le 21/11/2009 à 11:47 Membre depuis le 15/06/2003, 7954 messages
La taille de l'exécutable généré c'est complètement subjectif et dépendant de la problématique.
Mais réduire la taille du code avant compilation c'est effectivement sans intérêt grin
Y'a après une différence entre ce que fait Kevin, qui est compresser le code à outrance (au point même d'en perdre la vraie signification), et compresser plusieurs lignes en une seule.
while (i != 0)
{
i = i - 1;
}
Par exemple c'est complètement redondant. Le fait que le "= i - 1" puisse être optimisé en "-= 1" ou "--" est laissé au choix du codeur, de préférence sur des critères de lisibilité du code.
Pour le reste, les { } sont par exemples inutiles (oui je les ai volontairement mis pour ça) donc ça va répartir le "code utile" inutilement sur 4 lignes au lieu de 2.
Ensuite le (!= 0) est par définition du langage C fait implicitement (implicitement mais de manière explicite, vous suivez ? tongue) par les structures du langage C (sinon on pourrait aussi écrire if (i != 0 != 0 != 0 != 0 != 0 [...]) jusqu'à obtenir comme résultat un bool, mais on peut attendre très longtemps...)
Ensuite, oui, le i-- (ou équivalent) peut carrément être mis à l'intérieur du while.
while (i--) ;
Est-ce vraiment moins clair ? Je trouve que ça a presque gagné en lisibilité moi.

Sinon, pour l'utilisation des trucs réducteurs tels que ++ et += par exemple, ce que je fais par exemple: (Règle 1 pour tous les <opérateur>=; Règle 2 uniquement pour += et -= )
1. Si c'est une opération "+ valeur" uniquement, réduire en "+=". Si c'est un "+ valeur1 + valeur2" alors non.
2. Si c'est réduit en "+=": Si c'est un "+ 1", et que ce n'est pas dans une série de "+=" (ou <opérateur>= quelconque), réduire en ++.

Aussi, l'espacement du code est important. Pas à outrance, mais encadrer les opérateurs binaires par des espaces, et insérer des lignes vides entre des blocs d'instructions sans grand rapport. Donc entre les fonctions, mais aussi dans les fonctions ^^
Certains voudront même mettre plusieurs lignes vides, mais en général au delà de 2 c'est clairement abusif et ça diminue la lisibilité plus qu'autre chose. (deux c'est déjà limite...)
avatar Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes
- Posté le 21/11/2009 à 12:03 Membre depuis le 13/06/2002, 39529 messages
Pour le "!= 0" c'est un sujet qui (comme beaucoup d'autres #hehe#) a déjà été abordé sur yAronet, et je suis du même avis qu'une majorité de yNautes (il me semble), à savoir que la seule chose à prendre en compte est le sens que porte la variable comparée :

- Quand on compare une variable numérique (un compteur par exemple), le "!= 0" et le "== 0" ne devraient pas être retirés. Oui ils sont implicites, mais on veut comparer sa valeur, donc un nombre. À partir de là on écrit pas "if (count)" en se disant qu'on est un vraie génie à avoir économisé 4 caractères, mais "if (count != 0)" ou "if (count == 0)" en se disant que "vérifier si le nombre d'éléments dans mon tableau est vrai", ça n'aurait aucun sens.

- À l'inverse, quand on compare une variable qui est utilisée comme booléen, il serait stupide d'écrire "== 0" ou "!= 0" : on ne veut pas la comparer à zéro, on veut savoir si elle vaut vrai ou faux. Donc "if (flag)" ou "if (!flag)".
avatar I invited your best friend the companion cube. Of course, he couldn't come because you murdered him.
------------------------------------------
Mirari² :: It offers what you want, not what you need
3l33t :: Relax, we understand j00 ^^
- Posté le 21/11/2009 à 12:21 Membre depuis le 15/06/2003, 7954 messages
Hmm oui c'est vrai ( ./83 ^^) le cas de la boucle vide ça marche bien sans le != 0 parce que c'est une sémantique type booleen cheeky
Dans le cas pratique c'est plutôt
while (i-- > 0) faire_quelque_chose(i);
avatar Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes
- Posté le 22/11/2009 à 22:03 Membre depuis le 18/06/2001, 30160 messages
Tiens, mon promier problème avec "static", que je ne connais pas. J'ai un Masked Big Sprite de Genlib, que j'initialise comme ça :
  MBGS Cursor =
{
16,
1,
{
0xFF
}
};

Le sprite est faux en dimension mais osef.
Si je ne le déclare pas en static, j'ai l'erreur :
error: non-static initialization of a flexible array member (near initialization for 'Cursor')

Quand je rajoute "static" à la déclaration, ça marche sans problème. Mais pourquoi ? Qu'est-ce que ça change ? Qu'est-ce que ça signifie dans ce contexte ? Pourquoi il n'y en a pas besoin pour mes autres données ? #confus#
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 22/11/2009 à 22:18 Membre depuis le 10/06/2001, 34971 messages
Le type Cursor est de taille variable, donc ne peut pas être alloué sur la pile.
avatar Mes news pour calculatrices TI: Ti-Gen (fr/en), MobiFiles (de)
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é
- Posté le 22/11/2009 à 23:09 Membre depuis le 18/06/2001, 30160 messages
Donc je suis obligé de lui dire moi-même qu'il ne va pas bouger ?
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 22/11/2009 à 23:14 Membre depuis le 10/06/2001, 34971 messages
Oui, et c'est à peu près ce que fait static. smile
avatar Mes news pour calculatrices TI: Ti-Gen (fr/en), MobiFiles (de)
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é
- Posté le 11/02/2010 à 12:23 Membre depuis le 18/06/2001, 30160 messages
Bon, je suis toujours embêté avec les libs dynamiques et la compilation.
Il y a des relogements, en soi pour le coup je m'en fous, mais tant qu'à faire j'aimerais bien les virer puisqu'il sont marqués comme "removables", et apparemment c'est pas fait.

J'ai mis ça dans kernel.h :
#define main _main
#define _main __main
#undef _main

(made in PpHdland)

Résultats des compilations :
tigcc -v -Wall -W -O2 -mno-bss --optimise-code --cut-ranges --reorder-sections --remove-unused -ffunction-sections -fdata-sections [...]

Program Statistics:
Program Variable Name: main\asti68k
Program Variable Size: 634 Bytes
Absolute Relocs: 6
Natively Emitted Relocs: 0
Relocs Removable by Move Optimization: 10
Space Savable by Using GAS `-l' Switch: 20 Bytes

Pour optimiser ça, puisqu'il dit pouvoir le faire, j'utilise -mpcrel :
======================================================================
*** Warnings ***
asti68k.o: Warning: Library calls cannot be relative; changing to absolute.
asti68k.o: Warning: Library calls cannot be relative; changing to absolute.
asti68k.o: Warning: Library calls cannot be relative; changing to absolute.
asti68k.o: Warning: Library calls cannot be relative; changing to absolute.
asti68k.o: Warning: Library calls cannot be relative; changing to absolute.
======================================================================
*** Errors ***
asti68k.o: Error: Cannot emit 2 byte library call to `butillib', function 0x0.
asti68k.o: Error: Cannot emit 2 byte library call to `butillib', function 0x2.
asti68k.o: Error: Cannot emit 2 byte library call to `butillib', function 0x3.
asti68k.o: Error: Cannot emit 2 byte library call to `butillib', function 0x6.
asti68k.o: Error: Cannot emit 2 byte library call to `butillib', function 0x1.
/opt/gcc4ti/lib/tigcc.a: Error: Library calls are not supported in this mode.
======================================================================

Alors, ce que je comprends, c'est que je lui demande de tout faire en pc-relatif. Il me balance un warning pour me dire qu'il peut pas écrire les appels de dll en pc-rel, c'est évident, il passe en absolu, très bien.
Mais alors pourquoi ces erreurs après ? Qu'et-ce qui lui va pas encore ? An'a marre ... #ouin#
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 11/02/2010 à 13:21 Membre depuis le 10/06/2001, 34971 messages
C'est --optimize-code, pas --optimise-code.

Et tu ne peux pas utiliser -mpcrel avec des libcalls. Un libcall est forcément un relogement.
avatar Mes news pour calculatrices TI: Ti-Gen (fr/en), MobiFiles (de)
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é
- Posté le 11/02/2010 à 13:28 Membre depuis le 18/06/2001, 30160 messages
Ok, je pensais qu'il savait se dire "je passe tout en pc-relatif sauf les libcalls, puisque évidemment c'est pas possible". Merci bien. smile
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 11/02/2010 à 14:00 Membre depuis le 18/06/2001, 30160 messages
J'ai ce code C :
	BufferSize1 = InitHandle(&Buffer1, BufferSize1, Name1);
BufferSize2 = InitHandle(&Buffer2, BufferSize2, Name2);
BufferSize3 = InitHandle(&Buffer3, BufferSize3, Name3);
BufferSize4 = InitHandle(&Buffer4, BufferSize4, Name4);

Qui donne ça :
.LC1:
.ascii "ab\0"
.LC2:
.ascii "cd\0"
.LC3:
.ascii "ef\0"
.LC4:
.ascii "ghijklm\0"
.section .text._main,"x"
.even
.globl _main
_main:
link.w %fp,#-20
movm.l #0x1830,-(%sp)
clr.b -1(%fp)
pea .LC1
pea 10.w
pea -4(%fp)
lea InitHandle,%a2
jbsr (%a2)
move.l %d0,%d4
pea .LC2
pea 10.w
pea -6(%fp)
jbsr (%a2)
pea .LC3
pea 10.w
pea -8(%fp)
jbsr (%a2)
lea (32,%sp),%sp
move.l #.LC4,(%sp)
pea 10.w
pea -10(%fp)
jbsr (%a2)

Pourquoi ce move.l #.LC4,-(%sp) ? Pourquoi pas un pea comme les autres ? Il me fout un relogement pour ça, c'est nul comme comportement #confus# Pourquoi, quel intérêt ? Et pourquoi procéder de deux manières différents pour deux cas strictement identiques ??
Et si je vire n'importe lequel de ces 4 appels de fonction, le relogement dégage... Comment forcer ça ??
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 11/02/2010 à 14:06 Membre depuis le 24/04/2002, 4656 messages
Attention, si tu regardes le code, tu verras qu'il n'y a pas de '-' devant "(%sp)", ce qui fait que cette instruction est différente d'un PEA.
avatar Maintenant j'ai la flemme de garder une signature à jour sur ce site. Je n'ai même plus ma chaîne Exec sous la main.
- Posté le 11/02/2010 à 14:11 Membre depuis le 18/06/2001, 30160 messages
Oui je sais (je me suis planté au-dessus), mais le problème n'est pas là. Il fait ça pour ne pas avoir à dépiler 4 octets, je fais ça aussi en assembleur. Mais 4 octets de pile, j'en ai rien à battre, pourquoi fait-il ça ? Pourquoi un relogement ? On perd plus de place de binaire que 4 malheureux octets de pile dont on a rien à foutre
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 11/02/2010 à 14:36 Membre depuis le 10/06/2001, 34971 messages
Parce que l'optimisation sur le register transfer language (RTL) qui fait ça n'est pas au courant des détails du jeu d'instruction 68k, probablement.
avatar Mes news pour calculatrices TI: Ti-Gen (fr/en), MobiFiles (de)
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é
- Posté le 11/02/2010 à 15:26 Membre depuis le 18/06/2001, 30160 messages
Et ya u moyen d'avoir un adressage relatif, même avec les appels de libs ? En sortant les appels de dll et en les mettant dans un autre fichier, puis en compilant séparément avec différentes options peut-être ?
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 11/02/2010 à 16:04 Membre depuis le 10/06/2001, 34971 messages
Et l'intérêt? Si tu as des appels de libs, tu as forcément des relogements, donc je ne vois pas pourquoi tu cherches à éviter les relogements internes à tout prix.
avatar Mes news pour calculatrices TI: Ti-Gen (fr/en), MobiFiles (de)
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é
- Posté le 11/02/2010 à 16:09 - Edité par Folco le 11/02/2010 à 16:24 Membre depuis le 18/06/2001, 30160 messages
Aucun intérêt c'est sûr. C'est juste que je voulais virer ce relogement que rien ne justifie techniquement.
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 11/02/2010 à 16:20 Membre depuis le 10/06/2001, 34971 messages
J'attends ton correctif pour GCC. tongue
avatar Mes news pour calculatrices TI: Ti-Gen (fr/en), MobiFiles (de)
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é
- Posté le 11/02/2010 à 16:25 Membre depuis le 18/06/2001, 30160 messages
Tu sais très bien que je peux pas y arriver j'ai pas le niveau. grin Maintenant, je suis sûr que d'autres vont le faire, merci d'avance à tous ! #top# #espoir#
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 11/02/2010 à 16:55 Membre depuis le 16/06/2001, 59946 messages
awww pauvre folco #tsss#
- Posté le 14/02/2010 à 15:15 - Edité par Folco le 14/02/2010 à 15:51 Membre depuis le 18/06/2001, 30160 messages
Autre question.
Si j'écris : return a-- + 1;
avec a type de base non pointeur (pour faire simple).

Est-ce exécuté comme ça ?
1. on stocke ret = a + 1
2. on décrémente a
3. on retourne ret = a + 1

Ou comme ça ?
1. on calcule ret = a - 1 + 1 (vu que a-- + 1 == a)
2. on décrémente a
3. on retourne ret = a

En fait, je ne sais pas ce que doit faire le langage :
- évaluation de l'expression, décrémentation de a et retour de l'expression réévaluée après la décrémentation
- évaluation de l'expression, retour de la valeur obtenue, et décrémentation de a juste avant le retour effectif

Ca me parait ambigu, et je n'ai pas trouvé dans mon bouquin quel est le comportement attendu et garanti dans ce cas-là.

edit -> rah je voulais parler d'un a-- et non d'un --a pour lequel c'est évident...
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 14/02/2010 à 15:37 Membre depuis le 04/05/2005, 3537 messages
Folco (./322) :
Est-ce exécuté comme ça ?
1. on stocke ret = a + 1
2. on décrémente a
3. on retourne ret = a + 1
Tes deux ret ont-ils la même valeur ? Sinon, pourquoi stocker une valeur inutile ?

Dans la seconde proposition, pourquoi décrémenter a deux fois ?

Tu peux simplement faire en premier les préincrémentations et prédécrémentations puis faire le calcul. Appliquer les postincrémentations et postdécrémentations et enfin retourner le résultat.
avatar
- Posté le 14/02/2010 à 15:48 Membre depuis le 15/06/2003, 7954 messages
La réponse à ta question est très simple Folco:
Tu peux considérer que --a est équivalent à (a -= 1), autrement dit équivalent à (a = a - 1). (Idem pour ++a)
C'est une pré-décrémentation (resp. pré-incrémentation) donc le comportement est simple, tu sais qu'elle a toujours lieu avant le reste des calculs, le reste n'a pas dimportance:
L'ordre où le stockage "physique" des variables est effectué peut varier selon le compilateur et les optimisations, et n'a par conséquent aucune importance (ton --a pourrait même ne jamais avoir lieu), et sauf exception, ça n'influencera jamais le déroulement logique de ton programme.
avatar Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes
- Posté le 14/02/2010 à 15:49 Membre depuis le 18/06/2001, 30160 messages
C'est pas ça que je demande, j'ai dû mal m'exprimer. Je veux savoir le comportement d'un 'return a-- +1', quelque soit ce que je veux faire.

CROSS ! Mon problème me semble évident avec un --a en effet, mais je pensais à a--, ce qui change tout (j'ai édité le post de ma question en remplaçant en conséquence).
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 14/02/2010 à 15:53 Membre depuis le 10/06/2001, 34971 messages
return --a + 1; est équivalent à --a; return a + 1;.
return a-- + 1; est équivalent à tmp = a + 1; --a; return tmp; ou à plus bas niveau %d0 = a + 1; --a; rts;.
C'est la différence entre prédécrémentation et postdécrémentation.

Maintenant, le compilateur n'est pas con, si a est local, il va optimiser ton return --a + 1; en return a;. smile
avatar Mes news pour calculatrices TI: Ti-Gen (fr/en), MobiFiles (de)
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é
- Posté le 14/02/2010 à 15:55 Membre depuis le 15/06/2003, 7954 messages
./325 > Ah c'est malin cheeky
Ben c'est un peu plus chiant car le post-incrément est effectué "après".
Mais c'est globalement pareil.
La norme te garantit que a++/a-- vaut a au moment de l'évaluation, et que a sera incrémenté/décrémenté après. (Je sais plus si "après" est directement après le ++/-- comme en C# ou à la fin de la ligne de code par contre, flemme de regarder, et de toutes façons il suffit de pas mettre deux ++/-- sur la même variable sur la même ligne tongue)
Donc tu fais return a-- + 1;
ça fait a + 1; ET a = a - 1; ET return "valeur";
Le reste est sans importance tongue
avatar Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes
- Posté le 14/02/2010 à 16:00 Membre depuis le 18/06/2001, 30160 messages
Ok ! Donc le '++' est exécuté après le calcul de toute l'expression.

Dans mon programme, 'a-- + 1' est un peu plus complexe, il s'agit de ça en réalité :
const char *GetNextArg(CMDLINE *Parser)
{
	Parser->ArgIt++;
	return Parser->ArgV[Parser->ArgIt - 1];
}

Je me demandais si j'aurais pu écrire :
	return Parser->ArgV[(Parser->ArgIt)++];

Pour retourner Parser->ArgV[Parser->ArgIt], puis incrémenter Parser->ArgIt
Ca fait bizare de se dire que les choses vont se passer comme si on effectuait une opération (en l'occurrence, l'incrémentation) après le retour. cheeky

re-GC-cross : Voilà pourquoi j'ai écrit en deux lignes grin
avatar <<< Kernel Extremist©®™ >>>
Saint Qt, priez pour nous.
- Posté le 14/02/2010 à 16:08 - Edité par GoldenCrystal le 14/02/2010 à 16:11 Membre depuis le 15/06/2003, 7954 messages
Oui ça peut te sembler un peu bizarre avec le coup du return, mais si tu réfléchis un peu, la ligne de code est éxécutée, le compilateur peut pas en zapper la moitié juste comme ça.
Donc ton ++/-- est forcément éxécuté quoi qu'il arrive (sauf bien entendu, si tu utilises des opérateurs de court-circuitage && ou || en même temps tongue)
En fait le return est une opération en deux temps (dans le cas où il y a une valeur de retour), ① obtenir la valeur de retour ② quitter la fonction.
Toutes tes opérations seront quoi qu'il arrive terminées avant le ② smile
Après ce qui compte est le comportement "apparent" donc le compilateur peut optimiser ça comme il veut, changer l'ordre de tes opérations, l'ordre des lignes de code, supprimer des opérations, etc… Mais ça ne te regarde pas smile
avatar Le scénario de notre univers a été rédigée par un bataillon de singes savants. Tout s'explique enfin.
T'as un problème ? Tu veux un bonbon ?
[CrystalMPQ] C# MPQ Library/Tools - [CrystalBoy] C# GB Emulator - [Monoxide] C# OSX library - M68k Opcodes
- Posté le 14/02/2010 à 16:08 Membre depuis le 21/06/2001, 10198 messages
(cross)
./328 : dans ton cas, l'écriture en une ligne est aussi correcte et plus claire je trouve (tu peux aussi virer les parenthèses)

sinon non, le ++ est exécuté avant le calcul de l'expression, c'est juste que GC a présenté le déroulement déjà optimisé par le compilo
sans optimisation, ça donne a1 = a; a = a + 1; ret = a1 + 1; return ret; et c'est ce comportement qui doit être conservé
avatar