Macro avec parametre variable

Macro avec parametre variable - C++ - Programmation

Marsh Posté le 04-07-2007 à 15:17:45    

Bonjour,
 
Je cherche à écrire une macro qui me permette de saisir un nombre variable de paramètre et j'obtiens quelque chose qui à priori fonctionne, mais ca ne me plait pas trop.
 
 
Voici le code de la macro:

Code :
  1. #define Log(_X,_Z) 
  2. do
  3.     if (mylog == true) {   
  4.         InternalLog(_X,0,__FILE__,__LINE__,Message##_Z);   
  5.     }
  6. }while(0)


 
La fonction Message :

Code :
  1. char * Message(const char *msg,...) {
  2.     static char szBuffer[1024] = {0};
  3.     va_list vl; va_start(vl,msg); vsprintf(szBuffer,msg,vl); va_end(vl);
  4.     return szBuffer;
  5. }


 
Et du coup, je peux appeler ma macro par exemple de la facon suivante :

Code :
  1. Log(LOGLEVEL_TRACE,("Test %d %d",val1,val2));


 
 
Avec la bidouille qui consiste à concaténer la fonction Message avec _Z, _Z étant égal à ("mon message %d %d",val1,val2) dans mon exemple, j'arrive à appeler une macro avec un nombre variable de paramètre, mais à condition d'avoir les parenthèses autour de  "mon message %d %d",val1,val2. Sinon, je me prends un warning du compilateur qui me dit qu'il n'y a pas le bon nombre de paramètre (normal).
 
Du coup, quand on lit la syntaxe de la ligne, on pense qu'il y a une erreur et j'aimerais supprimer ce dernier problème, mais je ne vois pas comment faire (mes connaissances en préprocesseur sont limitées), alors peut-être certains ont une idée ou une astuce pour faire cela ?
 
Précision : il est important pour moi que Log soit une macro et non une fonction (avec une fonction je n'aurais pas ce problème), car je dois pouvoir retirer les lignes de log à la compilation selon si je suis en debug ou en release.
 
Merci d'avance :)
 
edit : fonction wysiwyg du forum qui deconne avec les balises code :(


Message édité par xilebo le 12-07-2007 à 15:38:11
Reply

Marsh Posté le 04-07-2007 à 15:17:45   

Reply

Marsh Posté le 04-07-2007 à 15:30:36    

J'en profite également pour poser une seconde question :
 
y a t il possibilité de générer des fichiers sources intermédiaires avec les macros expansés avec visual C++ 6.0 et gcc sous linux ?

Reply

Marsh Posté le 04-07-2007 à 15:32:07    

presque. mais faut lire la doc pour y arriver.
 

Code :
  1. #define debug(FMT, ...) debug_real(__FILE__, __LINE__, __func__, FMT, ##__VA_ARGS__)

par exemple

Reply

Marsh Posté le 04-07-2007 à 16:16:50    

Pour ta 2ème question : gcc -E
 
Pour ta première question : http://gcc.gnu.org/onlinedocs/gcc/Variadic-Macros.html

Reply

Marsh Posté le 04-07-2007 à 16:24:24    

Merci à vous 2. Si je n'ai pas trouvé rapidement, c'est que j'ai d'abord cherché dans l'aide de visual studio (parceque je développe par défaut sous cet IDE), et forcément, cette fonctionnalité n'est pas implémentée dans la version que j'utilise (V 6.0). Je suis en train d'installer visual studio 2005 qui apparemment supporte __VA_ARGS__.

Reply

Marsh Posté le 05-07-2007 à 08:27:55    

pouvez pas lire le standard tout simplement ...

Reply

Marsh Posté le 05-07-2007 à 09:32:39    

:sarcastic:
T'as appris le C en lisant le standard peut-être ? Sans compter que tout ce qui est ISO est payant.

Reply

Marsh Posté le 05-07-2007 à 10:14:53    

Reply

Marsh Posté le 05-07-2007 à 12:29:50    

C'est pas du poulet mais c'est pas non plus le standard. En plus franchement dans ton document, y'a quasiment que dalle sur __VA_ARGS__.

Reply

Marsh Posté le 12-07-2007 à 15:36:41    

Je réup ce message , et je le change de catégorie (c->c++) , pour savoir s'il est possible d'utiliser les macros à arguments variables non plus avec un compilateur C, mais un compilateur C++.
 
le compilateur que j'utilise est g++ version 2.95.4 et j'ai l'impression qu'il est un peu trop vieux pour cette syntaxe  :??:

Reply

Marsh Posté le 12-07-2007 à 15:36:41   

Reply

Marsh Posté le 12-07-2007 à 15:39:25    

il est trop vieux tout court, mais même si ça ne support pas bien C99, bah RTFM, y a probablement une extension GNU pour faire ça.


Message édité par Taz le 12-07-2007 à 15:40:08
Reply

Marsh Posté le 12-07-2007 à 16:44:47    

bon, je suis deg, je ne peux pas faire ça :  
 

Code :
  1. #include <stdio.h>
  2. #include <stdarg.h>
  3. #define EXPAND_VA(x,b)
  4. do{
  5.     va_list vl;
  6.     va_start(vl,x);
  7.     vsprintf(b,x,vl);
  8.     va_end(vl);
  9. }while(0)
  10. #define Log(_FMT,...)
  11. do {
  12.     if (MyLog::lpUniqueInstance) {
  13.     MyLog::lpUniqueInstance->InternalLog(__FILE__,__LINE__,_FMT,##__VA_ARGS__);
  14.     }
  15. }while(0)
  16. class MyLog{
  17.     public :
  18.     static MyLog *    GetInstance(void);
  19.     static void            FreeInstance(void);
  20.     static MyLog *    lpUniqueInstance;
  21.     static int            instanceCount;
  22.     MyLog();
  23.     virtual ~MyLog();
  24.     void InitLog();
  25.     void ShutLog();
  26.     void InternalLog(char *file, long line,const char *msg,...);       
  27. };
  28. MyLog *MyLog::lpUniqueInstance = NULL;
  29. int MyLog::instanceCount = 0;
  30. MyLog *MyLog::GetInstance(void) {
  31.     if (instanceCount++ == 0)
  32.         lpUniqueInstance = new MyLog();
  33.     return lpUniqueInstance;
  34. }
  35. void MyLog::FreeInstance(void) {
  36.     if (--instanceCount == 0) {
  37.         delete lpUniqueInstance;
  38.         lpUniqueInstance = NULL;
  39.     }
  40. }
  41. MyLog::MyLog() {
  42. }
  43. MyLog::~MyLog() {
  44. }
  45. void
  46. MyLog::InitLog() {
  47. }
  48. void
  49. MyLog::ShutLog() {
  50. }
  51. void
  52. MyLog::InternalLog(char *file, long line,const char *msg,...) {
  53.     char myMsg[1024] = {0};   
  54.     EXPAND_VA(msg,myMsg);   
  55.     printf("(%s:%d) %sn",file,line,myMsg);   
  56.        
  57. }
  58. int main() {
  59.     MyLog *pLog = MyLog::GetInstance();
  60.     if (!pLog) {
  61.         return 1;
  62.     }
  63.    
  64.     pLog->InitLog();
  65.    
  66.    
  67.    
  68.    
  69.    
  70.     pLog->ShutLog();
  71.     if (pLog) {
  72.         MyLog::FreeInstance();
  73.     }
  74.    
  75.     return 0;
  76. }


 
Lorsque je compile le programme avec gcc v 2.95.4 (sous debian woody 3.0, et glibc 2.2) il me renvoie l'erreur suivante :
 

Code :
  1. test.cpp:17: badly punctuated parameter list in '#define'


 
alors qu'avec gcc v 4.0.3 sous ubuntu (et visual 2005), ce code compile parfaitement bien.

Reply

Marsh Posté le 12-07-2007 à 19:05:27    

Faudrais voir à pas oublier les \ pour casser ta macro sur plusieurs lignes :o

Reply

Marsh Posté le 12-07-2007 à 23:21:39    

Joel F a écrit :

Faudrais voir à pas oublier les  pour casser ta macro sur plusieurs lignes :o


Ils y sont, c'est les balises code qui les ont viré :p

Reply

Marsh Posté le 13-07-2007 à 10:02:16    

xilebo a écrit :

Ils y sont, c'est les balises code qui les ont viré :p


OK donc ... ^^

 

Ensuite

Citation :


Lorsque je compile le programme avec gcc v 2.95.4 (sous debian woody 3.0, et glibc 2.2)


Ensuite, je susi pas sur que le 2.95 supporte cette tambouille


Message édité par Joel F le 13-07-2007 à 10:20:58
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed