Annonces Google
Serveur IRC
Serveur : irc.portlane.se
Canal : #AmigaNG
Activité du Site

Pages vues depuis 25/07/2007 : 25 179 389

  • Nb. de membres 187
  • Nb. d'articles 1 270
  • Nb. de forums 19
  • Nb. de sujets 20
  • Nb. de critiques 24

Top 10  Statistiques

Index du forum »»  Création-Développement »» Les macros et le langage C

Les macros et le langage C#2256

10Contributeur(s)
thellierK-LSharynnCrisotcortoElwoodsinisrusastrofra
3 Modérateur(s)
K-LElwoodcorto
thellier thelliericon_post

Hello

Suite à conversation que j'ai eu avec HunoPPC hier
Je réalise que les programmeurs C n'ont pas toujours comme moi le réflexe d'utiliser des macros partout dans leurs sources
Pourtant les macros simplifient la vie :-)

En voici qques unes que j'utilise très souvent

Un macro en C est un peu comme un raccourci clavier : c'est comme si vous aviez tapé le code à cet endroit mais écrit en "raccourci"
Je veux dire ce n'est pas un "sous programme" mais juste le compilateur qui fera un chercher/remplacer et remplacera au final votre "jargon"
par des instructions C standards

Exemple

#define HELLOWORLD printf("Hello World\n")

Après si vous tapez
HELLOWORLD;
HELLOWORLD;
HELLOWORLD;
dans votre code alors ils seront remplacés par les printf correspondant

Dès lors que vous utilisez plusieurs fois un truc dans une expression vous avez des "chances" de faire une erreur de saisie : par exemple les classiques
for(x=0;xou
printf("x:%ld\n",x);
y a t'il bien x marqué partout ? combien de fois on se trompe lors de copier/coller malencontreux...


REM me sert afficher du texte

LL LLL LLL à afficher les numeros de lignes : en cas de plantage faire préceder ses lignes de LL et obtenir ainsi la dernière ligne qui marche
ici OSAlert() affiche un requesteur texte à cliquer LLLL le met dans une variable globale ainsi en cas de plantage (GRIM) on retrouve cette valeur dans un registre

VAR VARF VARS VARP le contenu d'une variable int,float,string,pointeur

et ou AND OR me permettent de bien différencier les AND/OR binaires des et/ou servant aux conditions

MYCLR vide une structure

NLOOP fait une boucle

MYNEW MYNEWLIST alloue une structure, une list

CHECK RCHECK verifie un pointeur sinon return ou return(null)

COPYV copie des vecteurs x y z

INFO INFO2 à tester des valeurs
    INFO(action,GML_ac_move_direction )
    INFO(action,GML_ac_move_free )
    INFO(action,GML_ac_move_towards_point )
    INFO(action,GML_ac_set_hspeed )

SWAP à permuter deux variables quelconques

LIBOPEN LIBOPEN4 LIBCLOSE LIBCLOSE4 à ouvrir/fermer les libraries proprement :
BOOL OpenAmigaLibraries(void)
{
 LIBOPEN(DOSBase,dos.library,36L)
 LIBOPEN(GfxBase,graphics.library,0L)
 LIBOPEN4(IDOS,DOSBase)
 LIBOPEN4(IGraphics,GfxBase)
 return(TRUE);
}
void CloseAmigaLibraries()
{
 LIBCLOSE4(IDOS)
 LIBCLOSE4(IGraphics)
 LIBCLOSE(DOSBase)
 LIBCLOSE(GfxBase)
}

A noter aussi que vous pouvez faire des macros "conditionnelles" qui n'apparaitront que dans certaines versions de vos binaires genre :

#ifdef DEBUGVERSION
#define REM(message)  if(debug) {printf(#message"\n");}
#define    VAR(var)   if(debug) {printf(" " #var "=" ); printf("%ld;\n",  ((ULONG)var)  );}
#else
#define REM(message)  ;
#define    VAR(var)   ;
#endif


/*==================================================================*/
UBYTE debugtext[256];
UBYTE   tmpname[256];
ULONG LLnum=0;
/*==================================================================*/
ULONG asmline=0;
#define REM(message)  if(debug) {printf(#message"\n");}
#define STEP(tex)     {OSAlert(#tex);}
#define ZZ            {if(debug) OSAlert("OK");}
#define LL            {printf("Line:%ld %ld\n",(LONG)__LINE__,(LONG)LLnum++);}
#define LLL           {LL ; OSAlert("OK");}
#define LLLL          { asmline= __LINE__ ;  printf("Line:%ld\n",asmline); }
#define    VAR(var)   if(debug) {printf(" " #var "=" ); printf("%ld;\n",  ((ULONG)var)  );}
#define    VARF(var)   if(debug) {printf(" " #var "=" ); printf("%2.2f;\n",  var)  );}
#define   VARS(var)   if(debug) {printf(" " #var "=<%s>;\n",var); }
#define   VARP(var)   if(debug) {if(var!=0) {printf(" " #var "=" ); printf("%ld;\n",  ((ULONG)var)  );} else {printf(" " #var "=NULL;\n");}}
#define PP(var)       {if(debug) printf(#var ": \t\t\t\t\t%ld \t bytes \t(%ld aligned) \n", sizeof(var) , sizeof(var)%4 );}
#define et  &&
#define ou  ||
#define AND &
#define OR  |
#define MYCLR(x)  memset(&x,0,sizeof(x));
#define NLOOP(nbre) for(n=0;n#define MLOOP(nbre) for(m=0;m#define XLOOP(nbre) for(x=0;x#define YLOOP(nbre) for(y=0;y#define ZLOOP(nbre) for(z=0;z#define WLOOP(nbre) for(w=0;w#define  MYNEW(obj) (struct obj*)malloc(sizeof(struct obj),#obj);
#define  MYNEWLIST(obj,nb) (struct obj*)malloc(sizeof(struct obj)*nb,#obj); if(debug) printf(#obj " nb:%ld\n",nb);
#define  RCHECK(obj) if(obj==NULL) return(NULL);
#define  CHECK(obj) if(obj==NULL) return;
#define COPYV(a,b)   { (a)->x=(b)->x; (a)->y=(b)->y; (a)->s=(b)->s; (a)->t=(b)->t; (a)->w=(b)->w;  }
#define INFO(var,const) if(debug) if(var==const)  {printf("    [" #const "]\n"); }
#define INFO2(var,const) if(debug) if(var==const) {printf("    [" #const "]\n"); }
#define SWAP(x,y) {temp=x;x=y;y=temp;}
/*==================================================================*/
#define LIBCLOSE(libbase)  if(libbase!=NULL) {CloseLibrary( (struct Library  *)libbase );   libbase=NULL; }
#define LIBOPEN(libbase,name,version)  libbase =(void*)OpenLibrary(#name,version);    if(libbase==NULL)  return(FALSE);
#ifdef OS4
#define LIBOPEN4(interface,libbase)    interface=(void*)GetInterface((struct Library *)libbase, "main", 1, NULL); if(interface==NULL) return(FALSE);
#define LIBCLOSE4(interface) if(interface!=NULL) {DropInterface((struct Interface*)interface );interface=NULL;}
#else
#define LIBOPEN4(interface,libbase)    ;
#define LIBCLOSE4(interface) ; 
#endif
/*==================================================================*/


Message édité par : thellier / 03-03-2016 14:12
Message édité par : thellier / 03-03-2016 14:16
K-L K-Licon_post
Intéressant, un peu comme une variable donc ?
--
AmigaONE X1000/1,8 Ghz (A-Eon), Radeon RX560, 2 Go de Ram et OS4.1 FE
Sharynn Sharynnicon_post
Oui en effet c'est une bonne idée et cela facilite les choses...

Je vais prendre exemple de cet idée et revoir certaines ligne de mon AmOS4 ou il me semble pouvoir faire des MACROs de bouts de code qui se répètent souvent entre plusieurs commandes.

Thanks to you Thellier !!!
Projet AmOS4 - Retour vers l'Amos sous OS4...

SAM440EP - A1200 3.1 de base
Crisot Crisoticon_post
Ah le vaste sujet des macros. Sur certains forums ils seraient prêts à s'entretuer sur le sujet :-) Car dans certains cas, les (grosses) macros peuvent remplacer des (petites) procédures et vice-versa :-)

Autant j'en ai abusé en assembleur, autant je trouve que le C est un langage suffisamment "efficiant" au kilomètre de code. J'en ai tout de même, mais très peu.

Ce que je trouve vicieux dans les macros, c'est que ça soulage tellement le code visuellement qu'on peut en arriver à pondre des codes très très lourds sans s'en apercevoir.

Après c'est clair que pour des printf de debug, pour un petit "swap()" maison, y'a pas à chier, c'est terriblement efficace...
--
AmigaOne X1000 - 2 Go DDR2 - Sapphire R9 280x Toxic - Crucial MX200 500 Go - Alim/Cooling BeQuiet
corto cortoicon_post
Oui, vaste sujet ... potentiellement de discorde :-)

Pour dire, je n'adhère pas à l'utilisation des macros autant que ça, parce que pour certaines, si tu ne codes pas dans le programme tous les jours, tu ne sais pas ce qui est réellement fait derrière.
Et dans tes exemples, il y a des noms de macros qui pour moi ne sont pas explicites et d'autres inutiles (AND, OR, MYCLR).

Je vois ça comme un curseur : tu le déplaces sur usage modéré, tu améliores la lisibilité, tu le déplaces sur usage à gogo, tu détériores la lisibilité.

Ce qui est intéressant dans ton code ... c'est que tu fais des choses qu'on ne devrait pas avoir à faire si on avait un bon debugger (et/ou des outils orientés dév).

Elwood Elwoodicon_post
Citation: Crisot 

Ah le vaste sujet des macros. Sur certains forums ils seraient prêts à s'entretuer sur le sujet :-) Car dans certains cas, les (grosses) macros peuvent remplacer des (petites) procédures et vice-versa :-)

sauf erreur, il y a une grosse différence : les macros sont remplacées dans le code lors de la compilation, du coup lors de l'exécution du code, il n'y a pas d'appel de procédure, donc c'est plus rapide.
--
Philippe Ferrucci
Avec une Sam460 et AmigaOS 4.1, je suis eco-responsable. Cool !
sinisrus sinisrusicon_post
Moi j'aime bien les macros sauce moutarde mais j'avoue que mariné au vin blanc c'est pas mal non plus :-)
--
Coin coin... amitheme.amiga-ng.org
Sam460 1,15Ghz - OS4.1FE - Radeon Saphir HD7750 R7 250E - 2Go de ram
Crisot Crisoticon_post
Elwood: Félicitation, t'as mis les deux pieds dedans :-)

Oui, une petite macro ne créé par d'appel de procédure... mais pour X utilisations, c'est X fois le poids du code en taille d'exécutable, en occupation mémoire, et surtout cache.

Une procédure n'aura pas ce travers. Mais à la place, ça génère des échanges sur la pile, et donc, des lenteurs.

Alors, alors, tu le vois le gros débat? :)

Bon dans tous les cas les macros proposées ne rentrent pas dans ces considérations, là ce sont juste des outils, pas des procédures "macroifiées". Mais tout comme Corto, j'ai du mal à cerner l'intérêt de certaines macros. & et && sont terriblement clairs sur leurs usages, alors que les macros "et" et "AND" portent à confusion. De même pour les loops.

Après l'important c'est de coder. :-)
--
AmigaOne X1000 - 2 Go DDR2 - Sapphire R9 280x Toxic - Crucial MX200 500 Go - Alim/Cooling BeQuiet
icon_post
Serait-il possible d'écrire des macros qui remplacerait le code 68k ?
Cela reviendra à ce qu'un code source 68k pourrait être compiler en C et donc être portable.
Utile pour ceux ne voulant pas décrocher du 68k et avoir les avantages du C et pour le portage de code assembler vers du C.

Possible ?

Kamelito
[addsig]
corto cortoicon_post
@Elwood Ca dépend ... les fonctions de petites tailles peuvent être automatiquement inlinées par le compilateur, ce qui fait qu'il intègre le code au lieu de faire un appel de fonction. Après, pour ce qui est des considérations sur la perf de ceci ou la perf de celà, je pense que c'est à la marge. Bidouiller dans ce sens en pensant jouer sur la perf n'est qu'une voie de garage d'après moi.

@kamelito Je ne suis pas sûr d'avoir compris mais je dirais "non".

Petites Annonces

0 annonce(s) publiée(s)

Consulter

AmigaOS 4.1

Laissez-vous tenter par
AmigaOS 4.1
AmiTheme

AmiTheme