0

Lets say we have defined macro SWAP:

#define SWAP(a,b) {\
int tmp = a; \
   a = b; \
   b = tmp;}\

and using SWAP we need to sort 3 numbers (just write another macro which uses macro called SWAP):

#define SORT(a,b,c) \
    (a > b) ? SWAP(a,b) : ((a > c) ? SWAP(a,c) : ((b>c) : SWAP(b,c)))

I wrote it like this but my code shows only some errors:

#include <stdio.h>

#define SWAP(a,b) {\
int tmp = a; \
   a = b; \
   b = tmp;}\

#define SORT(a,b,c) \
    (a > b) ? SWAP(a,b) : ((a > c) ? SWAP(a,c) : ((b>c) : SWAP(b,c)))

int main()
{
    int a = 1024, b =  7, c = 11;

    printf("a = %d b = %d\n", a, b);
    SWAP(a,b)
    printf("a = %d b = %d\n", a, b);

    printf("a = %d b = %d c = %d\n", a, b);
    SORT(a,b,c)
    printf("a = %d b = %d c = %d\n", a, b);

    return 0;
}

errors I get:

error: expected expression before ‘{’ token|
ᴜsᴇʀ
  • 1,109
  • 2
  • 9
  • 23
yak
  • 3,770
  • 19
  • 60
  • 111
  • What line is the error on? Errors come from specific lines. – abelenky Jan 22 '14 at 16:14
  • compile with -E option which writes source with pre-processor output – suspectus Jan 22 '14 at 16:18
  • 1
    You can't have *blocks* (i.e. brace-enclosed statements like `{ int tmp = a; a = b; b = tmp; }`) inside of *expressions* (groups of operators and other expressions which get evaluated into a value, like `x ? y : z`. It's just not allowed by the C language. If you convert your use of the ternary operator into a `if/else` statement, it should work fine, although I'd advise you strongly not to ever write a sorting function with macros like that. – Adam Rosenfield Jan 22 '14 at 16:20

3 Answers3

3

Let's expand your SORT(a,b,c) macro:

(a > b) ? SWAP(a,b) : ((a > c) ? SWAP(a,c) : ((b>c) : SWAP(b,c)))

Expanding each SWAP(a,b):

(a > b) ? {
int tmp = a;
a = b;
b = tmp;
} : ((a > c) ? {
int tmp = a;
a = c;
c = tmp;
} : ((b>c) : {
int tmp = b;
b = c;
c = tmp;
}))

This is not valid C code. That's why it fails to compile.

Define it like this:

#define SORT(a,b,c) \
    if(a > b) { SWAP(a,b) } else if(a > c) { SWAP(a,c) } else if (b>c) { SWAP(b,c) }

BTW, it's a good practice, to define multiline macros using dummy do-while loops (see: C multi-line macro: do/while(0) vs scope block ):

#define SWAP(a,b) do {\
int tmp = a; \
   a = b; \
   b = tmp;} while(0)\

This way, you can write it like a regular function call:

SWAP(a,b);
Community
  • 1
  • 1
Tamás Zahola
  • 9,271
  • 4
  • 34
  • 46
1

On compiling with gcc -E the SORT macro was expanded like this

 (a > b) ? {int tmp = a; a = b; b = tmp;} : ((a > c) ? {int tmp = a; a = c; c = tmp;} : ((b>c) : {int tmp = b; b = c; c = tmp;}))

The problem here are the braces and the semi colon in the SWAP function.

bashrc
  • 4,725
  • 1
  • 22
  • 49
0

@Tamas Zahola you need to modify

#define SORT(a,b,c) \
 if(a > b) { SWAP(a,b) } else if(a > c) { SWAP(a,c) } else if (b>c) { SWAP(b,c) }

this will not work if value of b will be greater then c in whole program.

sumit kumar
  • 602
  • 3
  • 11
  • 26