Reputation: 34
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
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
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
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
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
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
Reputation: 4738
Add braces for macro. It will work.
# define swap(a,b) { temp=a; a=b; b=temp;}
Upvotes: 0