News for hackers. Stuff that matters.
Re:Why does this C program compile? by jfaucett on Wednesday December 19, 2012 @01:38PM (#4943968)
this is pretty basic, I would hope no actual c programmers would ask this question. Compilers are fun aren't they, how bout this one:

  #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!");
  }
Re:Why does this C program compile? by whatshisface on Wednesday December 19, 2012 @02:55PM (#4944431)
I'm going to take a guess at this... the macros compile down to #define billy_bob main?

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?

Re:Why does this C program compile? by jfb on Wednesday December 19, 2012 @02:59PM (#4944458)
That's exactly right.
Re:Why does this C program compile? by npsimons on Wednesday December 19, 2012 @03:41PM (#4944690)
See, this is why I like HN. The discussion here is more interesting than the OP (which is, indeed, a very basic question that a little bit of research into the history of C would answer). I thought I knew about preprocessor magic (including stringification and variadic macros), but I'm glad to have run across this post (and the ensuing discussion) as I've learned something very useful from it (eg, how to construct more dynamic code in C/C++).
Re:Why does this C program compile? by kelnos on Thursday December 20, 2012 @01:06AM (#4946493)
To be pedantic, that's just preprocessor abuse... nothing really to do with the compiler proper.
Re:Why does this C program compile? by BadDesign on Wednesday December 19, 2012 @05:39PM (#4945217)
I think you mean preprocessors.
Re:Why does this C program compile? by habosa on Wednesday December 19, 2012 @02:42PM (#4944356)
Ok what in the world does that do?
Re:Why does this C program compile? by marssaxman on Wednesday December 19, 2012 @02:57PM (#4944448)
It's just a fancy way of assembling the identifier "main" without writing it explicitly. Inside a preprocessor macro definition, the double hash mark is an operator which concatenates its left and right operands. This is a lexical operation. The "yell" macro takes six arguments and returns the concatenation of arguments 2, 3, 0, and 1, ignoring 4 and 5.

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".

Re:Why does this C program compile? by ntumlin on Wednesday December 19, 2012 @02:35PM (#4944312)
Would you please explain the code?
Re:Why does this C program compile? by cnvogel on Wednesday December 19, 2012 @03:10PM (#4944511)
There's the "##" operator with which you can glue together identifiers with the preprocessor.

  #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; };
Re:Why does this C program compile? by kevinnk on Wednesday December 19, 2012 @02:50PM (#4944396)
>#include <stdio.h>

>#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!".

Re:Why does this C program compile? by dubya on Wednesday December 19, 2012 @02:51PM (#4944407)
Hint: the 't' and 'e' in yell(i,n,m,a,t,e) are irrelevant.