1

I have come across the following Macro and I cannot understand what it's doing exactly;

#include <iostream>
#define TEST(a1) \
  int a1 = 5; 

int main(){

   TEST(a1);
   std::cout << a1  << std::endl;

   return 0;
}

It compiles and prints 5.

I know macros to a degree but I cannot wrap my head around what is happening here. To me TEST looks like a function which is redefining its argument a1?

Joe
  • 31
  • 1
  • 4
  • In C and C++, macros act like a dumb copy 'n' paste (unless you do stuff like stringification or token concatenation). The token you pass when you "call" the macro is just getting pasted in the statement `int a1 = 5;` as part of the macro expansion. If you're using GCC or Clang, you can try [running just the preprocessor and looking at the output to see what's happening](https://stackoverflow.com/q/3916979/1287251). – Cornstalks Apr 12 '19 at 03:14
  • @Cornstalks ah sorry I have removed that part, an error on my side. But I still don't understand whats happening. What is being copied here? what is the end result – Joe Apr 12 '19 at 03:16
  • The `-E` option will make gcc/clang run just the preprocessor, and the will emit the final processed code (before compiliation). I recommend using [gcc.godbolt.org](https://gcc.godbolt.org/z/x7ExX8) as a simple way to explore macros and what they expand to (though heads up: if you `#include` a file you're in for a treat :)). – Cornstalks Apr 12 '19 at 03:20

1 Answers1

2

A macro just puts the code defined in the macro wherever you call the macro through the preprocessor

What it basically comes down to is that this code:

#include <iostream>
#define TEST(a1) \
  int a1 = 5; 

int main(){

   TEST(a1);
   std::cout << a1  << std::endl;

   return 0;
}

becomes this code:

#include <iostream>

int main(){

   int a1 = 5; 
   std::cout << a1  << std::endl;

   return 0;
}

in effect.

The advantage to a macro, is that you can use it multiple times. And, since our example is parameterized, we can use it with minor variations. So, for example, this code:

#include <iostream>
#define TEST(a1) \
  int a1 = 5; 

int main(){

   TEST(a1);
   std::cout << a1  << std::endl;

   TEST(a2);
   std::cout << a2  << std::endl;

   TEST(a3);
   std::cout << a3  << std::endl;

   return 0;
}

becomes:

#include <iostream>

int main(){

   int a1 = 5; 
   std::cout << a1  << std::endl;

   int a2 = 5; 
   std::cout << a2  << std::endl;

   int a3 = 5; 
   std::cout << a3  << std::endl;

   return 0;
}

There are lots of things you can do with macros, and I recommend you research them, but this will get you started.

EDIT: Also worth mentioning is that, if you wanted to, you could change this macro to:

#define TEST(a1,val) \
  int a1 = val; 

That way, you could control the initialization value independently if you like. So:

TEST(a4,8)

becomes:

int a4 = 8;