Por ejemplo, me gustaría hacer una macro de depuración que imprima una cadena de código antes de intentar ejecutarla. Supongo que debería verse algo así.
#define TRACE(string) printf("Trying to execute: %s\n",\"string\"); \ string ... void foo() { printf("1\n"); } void bar() { printf("2\n"); } int main() { ... foo(); TRACE(bar();); ... }Con salida esperada
... 1 Trying to execute: bar(); 2 ...Bueno, así no es como se hace: el compilador se queja de una sintaxis ilegal. ¿Hay alguna manera de hacerlo?
Necesitas usar stringification usando # :
#define TRACE(string) printf("Trying to execute: %s\n",#string); \ stringEjemplo completo:
#include <stdio.h> #define TRACE(string) printf("Trying to execute: %s\n",#string); \ string void foo() { printf("1\n"); } void bar() { printf("2\n"); } int main() { foo(); TRACE(bar();); }producción:
1 Trying to execute: bar(); 2Debe usar el operador de "cadena", # , que provocará la sustitución con "string" .
#define TRACE(string) printf("Trying to execute: %s\n", #string); \ stringAdemás de las respuestas anteriores, ajuste su macro alrededor de una construcción do { /* ... */ } while(0) , como en:
#define TRACE(string) do { \ printf("Trying to execute: %s\n", #string); \ string \ } while(0)De lo contrario, puede causar errores, por ejemplo
if(condition) TRACE(foo();) Si no lo ajusta alrededor de una construcción do { /* ... */ } while(0) , se llamará a foo() incluso si la condition es falsa. Si tiene una declaración else a continuación, incluso causará un error de sintaxis.
Para obtener más información, consulte ¿Por qué usar declaraciones do-while e if-else aparentemente sin sentido en las macros? .