Reputation: 41
Go through the following C code
# define swap(a,b) temp=a; a=b; b=temp;
main( )
{
int i, j, temp;
i=5;
j=10;
temp=0;
if( i > j)
swap ( i, j );
printf ( "%d %d %d", i, j, temp);
}
Compiler Output:
10 0 0
I am Expecting this output
10 5 0
Why am I wrong??
Upvotes: 2
Views: 652
Reputation: 160
Your problem is the if condition in this line:
if( i > j)
swap ( i, j );
After the preprocessor has replaced your define, these lines look like the following:
if( i > j)
temp=a; a=b; b=temp;
What you expect is the following:
if( i > j)
{temp=a; a=b; b=temp;}
which can be achieved by changing your define to
#define swap(a,b) {temp=a; a=b; b=temp;}
EDIT: As mentioned by others, a more robust solution would be to define the macro as
#define swap(a,b) do{temp=a; a=b; b=temp;}while(1)
This still requires the variable temp
to be declared by hand.
A good example of a type independent swap macro can be found here: https://stackoverflow.com/a/3982430/5237890
Upvotes: 2
Reputation: 4084
Another problem is the line
if( i > j)
In your case, i=5 and j=10, so the first statement of theswap()
line is not executed. As @Kninnug pointed out (almost), without curly braces your code is actually
if(i > j)
temp = i;
i = j
j = temp;
Now, since I=5 and j=10, only the last two lines are executed, so I becomes 10 (the value of j) and j becomes zero (the value of temp).
Upvotes: 1
Reputation: 1
It is much better to define statement-like macros with a do{
...}while(0)
like (see this):
#define swap(a,b) do { int temp=a; a=b; b=temp; } while(0)
since the do{
....}while(0)
construct is correctly understood (even as the then or else
part of a conditional, etc. etc... as explained in other replies.
Actually, you'll still have issues if you invoke swap
with a temp
argument (e.g. swap(temp,xx)
) or if you use it with a side effecting second argument (e.g. swap(x,y++)
would increment y
twice and not do what you want).
A pedantically robust swap
might use concatenation at preprocessing level and some unique counter like the GCC specific __COUNTER__
predefined macro to generate a unique symbol (instead of temp
)
Upvotes: 5
Reputation: 1037
When using a function-like macro the compiler just replaces the text in the code where you call the function with the text in your macro declaration. You did not use curly braces after the if statement which would be fine if you only needed to execute one line of code. But when the compiler does the text replacement for your macro function, there are now three lines of code that need to be nested under the if statement.
Adding curly braces around the line Swap ( a, b )
will fix your problem. Alternatively you can place curly braces around the three lines of code in your macro declaration.
Upvotes: 0
Reputation: 3315
You should add curly braces to your macro declaration to solve your problem.
Moreover, if you want to swap basic type, like int for example, you can use the XOR operator to swap the values without use an additional variable.
#define swap(a, b) { a ^= b; b ^= a; a ^= b; }
Upvotes: 2
Reputation: 8053
It's the lack of braces. This is one of the common pitfalls with macros. Let's see what happens:
if(i > j)
swap(i, j);
becomes:
if(i > j)
temp = a; a = b; b = temp;;
Made a little more readable:
if(i > j)
temp = a;
a = b;
b = temp;
So the lines a = b;
and b = temp;
will always be executed, they fall outside the if
body.
Either put braces around the if
, or the macro.
Upvotes: 5