4

For example I'd like to make a debug macro which prints a code string before attempting to execute it. I suppose it should look something like that

#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(););
  ...
}

With expected output

...
1
Trying to execute: bar();
2
...

Well, THIS is not how one does it: compiler complains about illegal syntax. Is there a way to do it at all?

3 Answers3

11

You need to use stringification using #:

#define TRACE(string) printf("Trying to execute: %s\n",#string); \
                      string

Full example:

#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(););
}

output:

1
Trying to execute: bar();
2

live example on ideone

m.s.
  • 16,063
  • 7
  • 53
  • 88
8

You must use the "stringification" operator, #, which will cause substitution with "string".

#define TRACE(string) printf("Trying to execute: %s\n", #string); \
                      string
3

In addition to the previous answers, wrap your macro around a do { /* ... */ } while(0) construct, as in:

#define TRACE(string) do { \
                          printf("Trying to execute: %s\n", #string); \
                          string \
                      } while(0)

Otherwise, it may cause errors, e.g.

if(condition)
    TRACE(foo();)

If you do not wrap it around a do { /* ... */ } while(0) construct, foo() will be called even if condition is false. If you have an else statement following, it will even cause a syntax error.

For more information, see Why use apparently meaningless do-while and if-else statements in macros?.

Community
  • 1
  • 1
user12205
  • 2,684
  • 1
  • 20
  • 40