When I use this code:
#include
#define STR(x) #x
int main(void)
{
printf(__FILE__ STR(__LINE__) \"hello!\\n\");
return 0;
}
<
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.
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.