2016-05-10 55 views
6

Per favore aiutatemi a risolvere questo problema. Questo è un codice di esempio per ottenere il numero di riga, il nome del file e le variabili in C. Quando ho tentato di eseguirlo, ho ricevuto alcuni errori. Sono sicuro che ci sono molti modi per farlo. Ma devo usare il codice esistente per ottenere alcune funzionalità. Qualsiasi aiuto o suggerimento sarebbe molto apprezzato.Macro all'interno della macro in C

#include <stdio.h> 
#include <stdlib.h> 
#include <stdarg.h> 

#define MY_MACRO1(fmt, args...)    \ 
{            \ 
    char buf_d[1024];      \ 
    MY_MACRO2(__FILE__, __LINE__,call_func(buf_d,sizeof(buf_d),fmt,##args)); \ 
} 

#define MY_MACRO2(__FILE__, __LINE__,fmt, ...) printf("%s : %d -> %s : \n",__FILE__, __LINE__, __VA_ARGS__); 

char * call_func(char *buf_t, size_t size, const char *fmt, ...) 
{ 
    va_list ap; 
    va_start(ap,fmt); 
    vsnprintf(buf_t, size, fmt, ap); 
    va_end(ap); 
    return buf_t; 
} 


int main() 
{ 
    printf("\n Now I am printintg macro....\n"); 
    MY_MACRO1("Macro is working fine..\n"); 
    return 0; 
} 

uscita:

Si prega di trovare la macro di espansione. L'ultimo argomento nella macro (func return value) manca.

char buf_d[1024]; 
printf("%s : %d -> %s : \n","file.c",35,);; 

Errore: generato

file.c:35:83: error: expected expression 
{ char buf_d[1024]; printf("%s : %d -> %s : \n","file.c", 35,);; }; 
                  ^

1 errore.

+3

Elefante: Perché utilizzare una macro? – user4581301

+3

Perché eseguire il doppio tag di questo C e C++ quando non è né l'uno né l'altro? Stai usando un'estensione compilatore non standard di un compilatore che non hai specificato nella domanda. Deve diventare valido C? Deve diventare C++ valido? Deve diventare accettabile per il tuo particolare compilatore? Tutti e tre ti darebbero risposte diverse. E perché mai scegliere di ridefinire '__FILE__' e' __LINE__' come parametri macro ?! – hvd

+0

IIRC 'fmt, args ...' seguito in seguito da un ', ## args' è un'estensione non portatile. Puoi usare '...' al posto di 'fmt, args ...' e '__VA_ARGS__' al posto di' fmt, ## args' – technosaurus

risposta

1

Quando si utilizza , ... significa che è necessario fornire un argomento, che non è il tuo caso. Puoi semplicemente modificare la tua macro nominando la lista degli argomenti e lasciare che il preprocessore eludesse la virgola se necessario:

#define MY_MACRO1(fmt, args...)    \ 
{            \ 
    char buf_d[1024];      \ 
    MY_MACRO2(__FILE__, __LINE__,call_func(buf_d,sizeof(buf_d),fmt,##args)); \ 
} 

#define MY_MACRO2(F,L,fmt,args...) printf("%s : %d -> %s : \n",F, L, fmt, ##args) 
+0

test_macro.c: 30: 2: avviso: più conversioni '%' rispetto agli argomenti dati [-Wformat] Penso che tu abbia ragione Jean.Ma quando ho provato ho ricevuto il seguente avviso .. Sta stampando un po 'di spazzatura invece della stringa desiderata..test_macro.c: 20: 69: nota: espansa dalla macro' DEBUG_APMD_V2 ' #define DEBUG_APMD_V2 (file, riga, fmt, args .. .) printf ("% s:% d ->% s: \ n", file, riga, ## args); ~^ 1 avviso generato. – Rock26

+0

Il tuo esempio modificato come ho suggerito funziona per me, potrebbe essere la tua situazione reale è un po 'diverso? –

+2

Si noti che la notazione senza la virgola prima dei puntini di sospensione è un'estensione GCC (e probabilmente Clang-per-compatibilità-con-GCC). –

2

Che casino! Puliamo le cose:

Il codice:

#include <stdio.h> 
#include <stdlib.h> 
#include <stdarg.h> 


#define DEBUG_MSG(_msg, ...) do {print_debug_msg(__FILE__, __LINE__, __FUNCTION__, _msg, ## __VA_ARGS__); }while(0) 


void print_debug_msg(const char * module, int line, const char * func, const char * fmt, ...) 
{ 
    va_list va; 
    char buf[ 1024 ] = {0}; 

    va_start(va, fmt); 
    vsnprintf(buf, sizeof(buf), fmt, va); 
    va_end(va); 

    printf("%s:%d - %s() - %s\n", module, line, func, buf); 
} 


int myfunc(const char * msg) 
{ 
    DEBUG_MSG("Message: %s", msg); 

    return 0; 
} 


int main(int argc, char * argv[]) 
{ 
    DEBUG_MSG("The quick brown fox jumps over the lazy dog."); 

    DEBUG_MSG("Pack my box with five dozen liquor jugs."); 

    myfunc("How vexingly quick daft zebras jump"); 

    myfunc("The five boxing wizards jump quickly."); 

    return 0; 
} 

/* eof */ 

di compilazione:

$ gcc -Wall macro.c -o macro 

Testing:

$ ./macro 
macro.c:32 - main() - The quick brown fox jumps over the lazy dog. 
macro.c:34 - main() - Pack my box with five dozen liquor jugs. 
macro.c:24 - myfunc() - Message: How vexingly quick daft zebras jump 
macro.c:24 - myfunc() - Message: The five boxing wizards jump quickly. 

Riferimenti:

1) Recommended C Style and Coding Standards (Macros)

2) GCC Manual - Standard Predefined Macros

Spero che aiuti!