Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The best way to define a "between" macro in C

What's the best way to define a between macro, which is type generic (char,int,long) which will return true if a number is between to other numbers inputted. I'm tried to google it, but I didn't find anything.

Edit: The order of the two boundaries given shouldn't matter. so it can be more general.

like image 836
stdcall Avatar asked Oct 25 '25 20:10

stdcall


2 Answers

If you do something like:

#define BETWEEN(a, b, c)  (((a) >= (b)) && ((a) <= (c)))

you are going to have problem with the double evaluation of a. Think what would happens if you do that with a functions that has side effects...

you should instead do something like:

#define BETWEEN(a, b, c) ({ __typeof__ (a) __a = (a); ((__a) >= (b) && ((__a) <= (c)) })

(edited because the result should not depend of the order of b and c):

#define BETWEEN(a, b, c) \
           ({ __typeof__ (a) __a = (a);\
              __typeof__ (b) __b = (b);\
              __typeof__ (c) __c = (c);\
               (__a >= __b && __a <= __c)||\
               (__a >= __c && __a <= __b)})
like image 83
Teudimundo Avatar answered Oct 27 '25 15:10

Teudimundo


Firstly, don't use macros for things like this - use functions (possibly inline).

Secondly, if you must use macros, then what's wrong with e.g.

#define BETWEEN(x, x_min, x_max) ((x) > (x_min) && (x) < (x_max))

?

As per your subsequent edit, if you don't know the ordering of x_min and x_max then you could do this:

#define BETWEEN2(x, x0, x1) (BETWEEN((x), (x0), (x1)) || \
                             BETWEEN((x), (x1), (x0)))

The usual caveats about macros and side-effects etc apply. Edit: removed space between macro & arguments for compilation

like image 43
Paul R Avatar answered Oct 27 '25 14:10

Paul R