user3347767
user3347767

Reputation: 34

I executed following code with macro

I executed following code

# define swap(a,b) temp=a; a=b; b=temp;
#include<stdio.h>
#include<conio.h>
main( )
{
  int i, j, temp;
  i=5;
  j=10;
  temp=0;
  if( i > j)
    swap( i, j );
  printf( "%d %d %d", i, j, temp);
}

It gave me output as 10 0 0

My question is why #define macro gets executed even after the if(i>j) statement is false?

Upvotes: 1

Views: 218

Answers (6)

user3368369
user3368369

Reputation: 98

Adding braces to your macro helps in scoping your code. When you write your macro without braces then it will get expand in this manner.

    if( i > j)
{
      temp=a; 
}
    a=b; 
    b=temp;

But when you add braces like this:-

#define swap(a,b) {temp=a; a=b; b=temp;}

Then your code will execute as per your expectation

Upvotes: 1

Vlad from Moscow
Vlad from Moscow

Reputation: 311038

If to insert the macro definition in the code then instead of

  if( i > j)
    swap( i, j );

you will get

  if( i > j)
    temp=i; i=j; j=temp;

It will look more clear if to format this code appropriately

  if( i > j) 
    temp=i; 

  i=j; 
  j=temp;

So in realty the if statement was not executed.

However the two statements that follow the if statement were executed.

So j was assigned to i and i becomes equal to 10 while temp was assigned to j and j becomes equal to 0,

This result you got.:)

If you do not want this result then you should enclose the macro definition in braces. For example

# define swap(a,b) { temp=a; a=b; b=temp; }

However it would be better to define variable temp as a local variable. For example

# define swap(a,b) { int temp=a; a=b; b=temp; }

In C++ you could use standard template function std::swap. The problem is that C has no references. Usually in C references are substituted for pointers. So the function could look as

void swap( int *a, int *b )
{
   int temp = *a;
   *a = *b;
   *b = temp;
} 

And in main you could call this function as

swap( &i, &j );

In C99 you could define this function as inline

inline void swap( int *a, int *b )
{
   int temp = *a;
   *a = *b;
   *b = temp;
} 

Upvotes: 0

spiritwolfform
spiritwolfform

Reputation: 2293

You need to wrap the macro into curly braces to make it work:

#define swap(a,b) {temp=a; a=b; b=temp;}

Your macro is expanded into the following

if( i > j)
  temp=a; 
a=b; 
b=temp;

And the proper solution is to use std::swap, which is a template function. You'll never run into this kind of problems with template functions

Upvotes: 6

user2249683
user2249683

Reputation:

You need a scope in that macro:

# define swap(a,b) do { temp=a; a=b; b=temp; } while(0)

Note: The do/while is avoiding pitfalls if it used as an expression.

But that macro is junk, anyway. It requires the variable temp declared outside, which is leading to the confusion in the first place.

In C++ just use std::swap.

Upvotes: 1

ouah
ouah

Reputation: 145879

Rewrite your macro like this:

#define swap(a, b) do { int temp = (a); (a) = (b); (b) = temp; } while (0)

Note that here I declare temp inside the compound statement, if you have to deal with different (larger) types, you could declare the temp variable in another scope like you did.

Upvotes: 3

Digital_Reality
Digital_Reality

Reputation: 4738

Add braces for macro. It will work.

# define swap(a,b) { temp=a; a=b; b=temp;} 

Upvotes: 0

Related Questions