#include <stdio.h>
#define yell(i,l,o,v,e,u) o##v##i##l
#define billy_bob yell(i,n,m,a,t,e)
billy_bob()
{
printf("no main in da house!");
} #include <stdio.h>
#define yell(i,l,o,v,e,u) o##v##i##l
#define billy_bob yell(i,n,m,a,t,e)
billy_bob()
{
printf("no main in da house!");
}Let's see... yell() takes six 'bare' strings and appends four of them together in a certain order while ignoring the other two. This turns (i,n,m,a,t,e) into (m,a,i,n). The second define sets billy_bob as the output of yell.
I don't know C very well, is this correct?
The billy_bob macro calls the yell macro, passing in some letters - if you look at which letters from "i,n,m,a,t,e" end up attached to which arguments in "yell", you'll see that "yell' rearranges 'i,n,m,a' to spell the word "main".
>#define yell(i,l,o,v,e,u) o##v##i##l
defines a macro called yell. The preprocessor operator ## concatenates it's operands together so something like ma##in gets transformed into main.
>#define billy_bob yell(i,n,m,a,t,e)
defines a macro called billy_bob that simply expands to the macro yell. When we call yell with the given arguments we get m##a##i##n (look at the order of the arguments for yell) which gets transformed into main.
>billy_bob()
Expanding the macro turns this line into main().
>{
> printf("no main in da house!");
>}
So now we've declared a main function that just prints "no main in da house!".
#define yell(i,l,o,v,e,u) o##v##i##l
yell(i,l,o,v,e,u) will turn into the identifier ovil.
And billy_bot just uses the yell-macro to produce a "main" identifier. #define billy_bob yell(i,n,m,a,t,e)
yell(i,l,o,v,e,u) --> o ## v ## i ## l
yell(i,n,m,a,t,e) --> m ## a ## i ## n
So billy_bop is main.Why is this features useful at all? When you actually want to programmatically create function names, type names, struct names in preprocessor generated code.
#define ENCAPS_STRUCT(type,name) struct encaps_##type { type name; }
ENCAPS_STRUCT(int,a);
will generate... $ cc -E test.c
# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "test.c"
struct encaps_int { int a; };