question bete de #define - C - Programmation
Marsh Posté le 07-05-2008 à 14:03:30
Si je me trompe pas le compilateur remplacera 3+4+5 par 12 lors d'une de ses phases d'optimisation.
Marsh Posté le 07-05-2008 à 14:03:54
Ta première analyse est bonne, l'expression "3+4+5" sera remplacée telle quelle dans le code.
Pour le calcul, si c'est déterminable avant la compilation (comme dans ton exemple), alors le compilateur le fera durant les phases d'optimisation. Plus bêtement, si le calcul est coûteux, tu peux définir directement le résultat avec un commentaire expliquant d'où sort ce nombre.
Marsh Posté le 07-05-2008 à 14:12:47
compile comme ça "gcc -E toto.c"
ça te craches le rendu du préprocesseur
Marsh Posté le 07-05-2008 à 14:20:50
je suis sous mplab (pas top) avec C18 comme compilo
merci pour les reponses
l'origine (que j'ai oublié de préciser) :
en fait je suis en phase de test et j'ai fait de petits reglages de timing (changement de quartz, prescaler etc...).
Le truc c'est que ce timing influe partout dans le code et j'en ai raz le bol de tout recalculer pour avoir toujours 1ms (ma reference actuelle)
Alors j'ai mis le calcul dans un
Code :
|
pour les autres endrois
Code :
|
ou
Code :
|
mais dans mon calcul il y a une puissance de 2... du coup le code ne tourne plus (calcul tres long) ; apres une reflexion de 1/4 de seconde j'ai remplacé la puissance de 2 par un decallage
Code :
|
et c'était bien plus rapide, mais ca prend tout de meme du temps (le calcul globale) d'où la question.
Sinon les calcul sont toujours déterministe et remplacable en direct, mais ca me soule de me farcire les 50 rechercher/remplacer
Marsh Posté le 07-05-2008 à 14:59:31
évite les macros. c'est chiant parce que ça se passe pas au niveau du C: pas de typage. Si ton compilateur a ça, crée des constantes avec const
Marsh Posté le 07-05-2008 à 15:28:20
ben oui mais là... pas possible de mettre la formule
j'ai hésité pour les autres constantes (notamment pour le passage par adresse) mais en meme temps je suis tres limité en ram... donc moins de variable declarée const, moins de conso ^^ (c'est vrai ca d'ailleurs ?)
Marsh Posté le 07-05-2008 à 15:33:10
bah ça dépend la taille de ta constante, mais les quelques instructions pour charger la constantes ça peut facilement etre plus léger que plusieurs définitions locales.
Marsh Posté le 07-05-2008 à 17:41:44
bon effectivement c'est assez chiant de ne pas avoir le type du #define...
il semble que le calcul sur 4oct ne fonction pas en define :
Code :
|
ne fonctionne pas (mauvais resultat)
alors que :
Code :
|
fonctionne
Marsh Posté le 07-05-2008 à 17:48:24
Uh ?!
Code :
|
$ a.out |
Marsh Posté le 07-05-2008 à 17:49:21
Est que t'as déjà entendu parlé du concept de promotion d'entier en C ? Parce que là, j'ai l'impression que tu colles des bouts de code pour que ça tombe en marche....
En l'occurence, ça :
Code :
|
Ça calcule la division entière entre l'entier 64bits 3456000000 et l'entier 102. Alors que ça :
Code :
|
Ça calcule la division réelle entre le réel 3456000000 et le nombre 102.4 (edit: le résultat sera ensuite converti en entier).
Normal que tu obtiennes 2 résultats différents, le préprocesseur n'y est stritement pour rien.
Marsh Posté le 07-05-2008 à 17:51:03
Ouais j'ai répondu pareil et effacé mon post juste après, à cause de :
// ou #define TEMPS_BESOIN1 3456000000/TEMPS_HORLOGE (au choix) ca fait pareil |
Marsh Posté le 07-05-2008 à 18:00:43
bon... chez moi ca ne donne pas le resultat de Elmoricq
mais en fait le 102.4 vient d'un calcul lui meme en maccro...
j'ai fait plusieurs essai sur ce calcul, il semble qu'il ne peut y avoir que 1 chiffre apres la virgule.... donc j'ai fait *10 et effectivement tout rentre d'ans l'ordre.
donc effectivement un blem d'entier... cela dit lors des essai j'ai remarqué que l'arrondi parfois differrait (ce qui ne me derangeait pas trop) du à la perte du 0.4 ; mais parfois le resultat etait incompréhensible, comme un débordement ou je ne sais quoi... d'ou le rajout de unsigned short
Bref c'est tou bon maintennat merci
PS : la seulle promo dont j'ai entendu parler est celle de canap
Marsh Posté le 07-05-2008 à 18:01:50
En ce cas, lis le post de tpierron, c'est exactement ton problème.
Marsh Posté le 07-05-2008 à 19:08:28
avec ou sens unsigned c'est pareil, C18 le fait de manière transparente ; mais il calcul aussi avec une taille étrange qui provoque (suivant l'ordre du calcul) des resultats tres étranges...
donc oui tpierron à raison, mais si c'était le probleme je m'enserrais vite accomodé
maintenant j'ai la précision que je souhaite pour faire 1min @10-3 1s @10-2 juste la 1ms à 8% ais bon c'est normale...
maintenant le blem, c'est de faire les divisions en rapide
edit : division autre que 2 evidement
Marsh Posté le 07-05-2008 à 20:49:31
C'est pas unsigned le problème qu'évoque tpierron, mais le fait que tu utilises des nombres décimaux dans des calculs d'entiers => promotion en entier => calcul faux.
Quand tu cast "102.4" dans un unsigned short, ce type étant entier, tu obtiens "102".
Et donc en faisant "3456000000 / (unsigned short)102.4" => tu calcules en fait "3456000000 / 102".
Marsh Posté le 08-05-2008 à 00:18:46
j'avais bine compris... le truc c'est que ... meme en prenant 102, le resultat ne collais pas il y avait comme un debrdement ou un passage en signé ... bref une valeur completement abérente...
en meme temps C18.... c'est pas une bete de compete de compilo (gratos fournit par microchip), je ne suis pas à la premiere bizarrerie du genre... le #elif ne fonctionne pas non plus
et les include de fichier qui ne finissent pas par une ligne vide non plus (tres dure à trouver celle là !! )
Marsh Posté le 08-05-2008 à 12:11:23
Toujours terminer ses fichiers par une ligne vide.
J'crois c'est même normé d'ailleurs.
Marsh Posté le 08-05-2008 à 15:37:35
Elmoricq a écrit : Toujours terminer ses fichiers par une ligne vide. |
Je suis curieux de savoir pour quelle raison technique cela a été décidé
Marsh Posté le 08-05-2008 à 16:02:51
ca date du glorieux temps antique je pense. C'est comme le coup des 80 colonnes de FORTRAN, une relique.
Marsh Posté le 08-05-2008 à 21:18:10
Citation : Si je me trompe pas le compilateur remplacera 3+4+5 par 12 lors d'une de ses phases d'optimisation. |
Lors de la phase de compilation. Evaluer les constantes littérale n'est pas une optimisation, c'est une obligation pour le compilateur.
Sinon on ne pourrait pas écrire
int tab[1+2];
Donc
x = 1 + 2 + y;
sera toujours transformé en 3 + y;
Par contre
x = 1 + y + 2;
pas forcément, ça dépend de l'optim.
Marsh Posté le 07-05-2008 à 13:59:10
heu voili :
quand je fait :
je suppose que TOTO est simplement remplacer par l'expression ? et non executé par la macro pour remplace TOTO par 12 ?
Donc comment peut faire en C pour calculer des bouts comme ci-dessus en precompilation ? (si c'est possible)
Newb inside comme vous l'aurez remarqué