What does ## (double hash) do in a preprocessor directive?
TLDR; ##
is for concatenation and #
is for stringification (from cppreference).
The ##
concatenates successive identifiers and it is useful when you want to pass a function as a parameter. Here is an example where foo
accepts a function argument as its 1st argument and the operators a
and b
as the 2nd and 3rd arguments:
#include <stdio.h>
enum {my_sum=1, my_minus=2};
#define foo(which, a, b) which##x(a, b)
#define my_sumx(a, b) (a+b)
#define my_minusx(a, b) (a-b)
int main(int argc, char **argv) {
int a = 2;
int b = 3;
printf("%d+%d=%d\n", a, b, foo(my_sum, a, b)); // 2+3=5
printf("%d-%d=%d\n", a, b, foo(my_minus, a, b)); // 2-3=-1
return 0;
}
The #
concatenates the parameter and encloses the output in quotes. The example is:
#include <stdio.h>
#define bar(...) puts(#__VA_ARGS__)
int main(int argc, char **argv) {
bar(1, "x", int); // 1, "x", int
return 0;
}
##
is the preprocessor operator for concatenation.
So if you use
DEFINE_STAT(foo)
anywhere in the code, it gets replaced with
struct FThreadSafeStaticStat<FStat_foo> StatPtr_foo;
before your code is compiled.
Here is another example from a blog post of mine to explain this further.
#include <stdio.h>
#define decode(s,t,u,m,p,e,d) m ## s ## u ## t
#define begin decode(a,n,i,m,a,t,e)
int begin()
{
printf("Stumped?\n");
}
This program would compile and execute successfully, and produce the following output:
Stumped?
When the preprocessor is invoked on this code,
begin
is replaced withdecode(a,n,i,m,a,t,e)
decode(a,n,i,m,a,t,e)
is replaced withm ## a ## i ## n
m ## a ## i ## n
is replaced withmain
Thus effectively, begin()
is replaced with main()
.