18

When I use this code:

#include <stdio.h>
#define STR(x) #x

int main(void)
{
    printf(__FILE__ STR(__LINE__) "hello!\n");
    return 0;
}

it prints

hello.c__LINE__hello!

but when I use this:

#include <stdio.h>
#define STR(x) VAL(x)
#define VAL(x) #x

int main(void)
{
    printf(__FILE__ STR(__LINE__) "hello!\n");
    return 0;
}

it prints

hello.c7hello!

what's the difference between

#define STR(x) #x

and

#define STR(x) VAL(x)
#define VAL(x) #x
Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985
vv1133
  • 739
  • 1
  • 8
  • 21

2 Answers2

13

Arguments to macros are themselves macro-expanded, except where the macro argument name appears in the macro body with the stringifier # or the token-paster ##.

In the first case, the argument of STR is not macro-expanded, and so you just get the name of the LINE macro.

In the second case, the argument of STR is macro-expanded when it is substituted into the definition of VAL, and so it works -- you get the actual line number because the LINE macro is expanded.

Anthony Blake
  • 5,328
  • 2
  • 25
  • 24
1

C99 N1256 standard draft 6.10.3.1/1 "Argument substitution":

After the arguments for the invocation of a function-like macro have been identified, argument substitution takes place. A parameter in the replacement list, unless preceded by a # or ## preprocessing token or followed by a ## preprocessing token (see below), is replaced by the corresponding argument after all macros contained therein have been expanded. Before being substituted, each argument’s preprocessing tokens are completely macro replaced as if they formed the rest of the preprocessing file; no other preprocessing tokens are available.

So # and ## make arguments be treated differently.

Ciro Santilli OurBigBook.com
  • 347,512
  • 102
  • 1,199
  • 985