5

This has been bugging me for some time, I came across this while solving some objective type questions in C.

#define SWAP(a,b,c) c t;t=a;a=b;b=t;

int main() {
    int x=10,y=20;
    SWAP(x,y,int);     
}

The code gives the correct answer: Working code

In C are we supposed to pass just a data type as an argument.This supposedly works here but I want to know how.Also two more questions related to this:

  1. If I want to swap using pointers, will it work
  2. Will this work if SWAP is defined as a function instead of a macro.
Gyapti Jain
  • 4,056
  • 20
  • 40
Tushar
  • 61
  • 1
  • 2
  • You can even use symbols in macros: `#define OP(a,b,op) a op b` and then `if ( OP(3, 5, <) ) printf("lol\n");` . So long as you don't use `,`, `)` or cause a digraph or trigraph of course :) – M.M Nov 04 '14 at 04:54
  • @Tushar what I understood by your second question is "You want to write generalized SWAP() function that will swap the values of any data type". and It is possible with template. – nitish005 Nov 04 '14 at 05:08
  • but you cant pass data type as an argument. :( – nitish005 Nov 04 '14 at 05:13

2 Answers2

7

Macros are pre-processed before compilation and you can virtually write anything in macros that would be replaced. In function arguments, you can not pass data types as arguments.

Side note:

#define SWAP(a,b,c) do { c t;t=a;a=b;b=t; } while(0)

is a safer macro implementation than the one mentioned by you. Moreover name t is quite common. If either of the argument name is t, this won't work as expected, so better choose some rare name. Capital letters are usually preferred in macro definition.

for ex: #define SWAP(a,b,c) do { c MACRO_TEMP_;MACRO_TEMP_=a;a=b;b=MACRO_TEMP_; } while(0)

SWAP(x,y,int); Becomes c t;t=a;a=b;b=t; where all occurances of c are replaced with int, a with x and b with y. Resulting in: ìnt t; t = x; x = y; y = t;

To understand the macros better, you can see the pre-processed output of your code. Output on my computer:

$ cat q26727935.c
#define SWAP(a,b,c) c t;t=a;a=b;b=t;

int main() {
    int x=10,y=20;
    SWAP(x,y,int);     
}

$ gcc -E q26727935.c 
# 1 "q26727935.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "q26727935.c"


int main() {
    int x=10,y=20;
    int t;t=x;x=y;y=t;;
}
$ 
  1. Macro is replacement at pre-processor stage, so swap will work even with pointers, although this is superfluous.

  2. In function you can not pass data type as arguments, so it won't work.

Gyapti Jain
  • 4,056
  • 20
  • 40
1
  1. Yes.
  2. No.

First of all, you have to know that when you are using macros, the argument will be replaced as they are. So, if you call SWAP(a, b, int*), it will be replace with

int* t;t=a;a=b;b=t;

and then the code will be compiled.

But when you're using functions, that won't happen and you're unable to pass data type as an argument to a function.

Sadjad
  • 1,661
  • 2
  • 13
  • 20