Reputation: 516
For the following program
#include <stdio.h>
# define swap(a,b) temp=a; a=b; b=temp;
int main( )
{
int i, j, temp;
i=5;
j=10;
temp=0;
if( i > j)
swap ( i, j );
printf ( "%d %d %d", i, j, temp);
return 0;
}
I get this output which i tested with different compilers :
10 0 0
I understand that had j been 5 and i been 10 the output would have been swapped. But, in this particular program the if statement is not executed. So, can someone please explain the reason why i get this output?
Upvotes: 1
Views: 713
Reputation: 222689
As others have noted, your swap
macro results in three statements, and only the first one becomes part of the if
statement.
The idiomatic way of writing such a macro is:
#define swap(a, b) \
do { temp = a; a = b; b = temp; } while (0)
Although using only brackets, omitting the do
and while (0)
, may appear to work, it will fail in situations like this:
if (something)
swap(a, b);
else
something
In this code, the author treats swap
as a normal function call, not knowing that the semicolon should be omitted. After preprocessing, this expands to:
if (something)
{ temp = a; a = b; b = temp; }
;
else
something
This results in a compilation error, since the else
does not immediately follow a single statement after the if
. Using the do … while (0)
form results in code such that swap(a, b);
is exactly a single statement and may be used anywhere a normal function call in that form may be used.
Upvotes: 1
Reputation: 31
As an alternative to wrapping the macro in brackets...
#define swap(a,b) {temp=a; a=b; b=temp;}
You could also replace the semicolons to ensure the macro expands to a single statement...
#define swap(a,b) temp=a, a=b, b=temp;
I prefer the 'bracket' approach as it better illustrates scope.
Upvotes: 0
Reputation: 106012
After expansion of the macro you code will look like
if( i > j)
temp=i;
i=j;
j=temp;
This is not what you expect like:
if( i > j)
{
temp=a;
a=b;
b=temp;
}
Upvotes: 0
Reputation: 2483
You need to wrap the macro swap
with brackets.
if (i > j)
{
swap(i, j);
}
Don't forget that a macro is simply a copy-paste operation performed by the pre-processor which results in the following:
temp = i;
i = j;
j = temp;
If you don't wrap it you end up with:
if (i > j)
temp = i;
i = j;
j = temp;
I don't think this is what you intended... :)
Upvotes: 4