user3250183
user3250183

Reputation: 516

Explain the output of the following c program

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

Answers (4)

Eric Postpischil
Eric Postpischil

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

Kirk
Kirk

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

haccks
haccks

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

bblincoe
bblincoe

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

Related Questions