-1
void fun()
{
// Essentially this is a function with an empty body
// And I don't care about () in a macro
// Because this is evil, regardless
#define printf(a, b) (printf)(a, b*2)
}

void main() // I know this is not a valid main() signature
{
  int x = 20;
  fun();
  x = 10;
  printf("%d", x);
}

I am having doubt with #define line ! Can you please give me some links documentation for understanding this line of code.Answer is 20.

  • Can you please elaborate on your "doubt"? What part of the program don't you understand? Is it the preprocessor macro? Something else? – Some programmer dude Jul 02 '16 at 06:31
  • #define printf(a, b) (printf)(a, b*2) What is the meaning of (printf) and how it is working in main function. Thank you in advance ! – BHARADWAJ U M Jul 02 '16 at 06:35
  • It looks like the compiler is just ignoring the parentheses around the `printf` in the `#define`. I don’t know why the compiler allows them in the first place, but you don’t need them. Also, that program is awful for reasons that you don’t seem concerned about, so I won’t mention them. – yellowantphil Jul 02 '16 at 06:44
  • 1
    It should be [`int main(void)`](http://stackoverflow.com/questions/204476/what-should-main-return-in-c-and-c) – Antti Haapala -- Слава Україні Jul 02 '16 at 08:12
  • Your `#define printf(a, b) (printf)(a, b*2)` simply creates a macro for `printf(a, b)` that says when `printf(a, b)` is called, execute `(printf)(a, b*2)`. Essentially the macro just doubles the value of the second argument and then prints it. – David C. Rankin Jul 02 '16 at 09:30

3 Answers3

2

The #define defines a preprocessor macro is processed by the preprocessor before the compiler does anything. The preprocessor doesn't even know if the line of code is inside or outside a function.

Generally macros are defined after inclusion of header files. i.e. after #include statements.

K J Gor
  • 750
  • 5
  • 17
1

Preprocessor macros are not part of the actual C language, handling of macros and other preprocessor directives is a separate step done before the compiler1. This means that macros do not follow the rules of C, especially in regards to scoping, macros are always "global".

That means the printf function you think you call in the main function is not actually the printf function, it's the printf macro.

The code you show will look like this after preprocessing (and removal of comments):

void fun()
{
}

void main()
{
  int x = 20;
  fun();
  x = 10;
  (printf)("%d", x*2);
}

What happens is that the invocation of the printf macro is replaced with a call to the printf function. And since the second argument of the macro is multiplied by two, the output will be 10 * 2 which is 20.

This program illustrates a major problem with macros: It's to easy to a program look like a normal program, but it does something unexpected. It's simple to define a macro true that actually evaluates to false, and the opposite, changing the meaning of comparisons against true or false completely. The only thing you should learn from an example like this is how bad macros are, and that you should never try to use macros to "redefine" the language or standard functions. When used sparingly and well macros are good and will make programming in C easier. Used wrongly, like in this example, and they will make the code unreadable and unmaintainable.


1 The preprocessor used to be a separate program that ran before the compiler program. Modern compilers have the preprocessor step built-in, but it's still a separate step before the actual C-code is parsed.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • @yellowantphil It's no different than using parentheses around any expression. It's not needed and won't make any difference. It might be that the one who come up with the horrible code had an old or buggy preprocessor that would otherwise try to recursively expand the macro otherwise? – Some programmer dude Jul 02 '16 at 06:48
0

Let me put this in another way.

printf() is an inbuilt standard library function that sends formatted output to stdout (Your console screen). The printf() function call is executed during the runtime of the program. The syntax looks likes this.

int printf(const char *format, ...)

But this program of yours replaces the printf() function with your macro before the compilation.

void fun(){
    #define printf(a, b) printf(a, b*2)
}
void main() {
   int x = 20;
   fun();
   x = 10;
   printf("%d", x);
}

So what happens is, before compilation the compiler replaces the inbuilt function call with your own user defined macro function with two arguments:

  1. a="%d" the format specifier and
  2. b=the value of x =10.

So the value of x*2 =20

Ranjith Kumar
  • 68
  • 1
  • 9