# Handy macros (C)

This article is a collection of useful C oneliners and macros. Each item in the collection includes some minimal code which demonstrates how the item can be used.

## Bound a value

Makes sure that value stays within the max - min range. The macro makes use of temporary variables ("`TEMP_whatever__`") to avoid possible side effects from evaluating an expression more than once (e.g., `i++` increments `i` every time it is evaluated).

The logic behind this macro is IF value < MIN THEN value=MIN ELSE (IF value > MAX THEN value=MAX ELSE value=value)

```<<macro_bounds.c>>=
#include <stdio.h>
#define bounds(value, min, max)  ((TEMP_VALUE__=(value))>(TEMP_MAX__=(max))?TEMP_MAX__:(TEMP_VALUE__<(TEMP_MIN__=(min))?TEMP_MIN__:TEMP_VALUE__))
int main(void)
{
int n;
int TEMP_VALUE__, TEMP_MAX__, TEMP_MIN__;
for(n=0; n<10; n++)
{
printf("n = %d Adjusted: %d\n", n, bounds(n,3,6));
}
return 0;
}
```

## Test for even numbers

Check if a non-negative integer is even (2, 4, 6, 8, 10, etc.). It also works for negative integers if the processor represents integers in two's complement form, as is typically the case.

```<<macro_iseven.c>>=
#include <stdio.h>
#define iseven(value) (!((value)&0x01))
int main(void)
{
int n;
for(n=0; n<65; n++)
{
printf("%d is%s even\n", n, iseven(n)?"":" not");
}
return 0;
}
```

## Test for powers of two

Check if a positive integer is power of two (2, 4, 8, 16, 32, 64, etc.). The macro makes use of a temporary variable ("`TEMP_VALUE__`") to avoid possible side effects from evaluating an expression more than once (e.g., `i++` increments `i` every time it is evaluated).

```<<macro_powoftwo.c>>=
#include <stdio.h>
#define ispoweroftwo(value) ((TEMP_VALUE__=(value))&&!((TEMP_VALUE__-1)&TEMP_VALUE__))
int main(void)
{
int n;
int TEMP_VALUE__;
for(n=0; n<65; n++)
{
printf("%d is%s power of two\n",n,ispoweroftwo(n)?"":" not");
}
return 0;
}
```

## Xor swap

Xor swap is an idiom for swapping two variables without using a temporary variable. Generally its use is no longer recommended, as compilers are better able to choose the best swap implementation in a machine-specific way.

```<<macro_xorswap.c>>=
#include <stdio.h>
#define xorswap(a, b) ((a)^=(b),(b)^=(a),(a)^=(b))
int main()
{
int n1=5;
int n2=7;
printf("Before xorswap() n1=%d, n2=%d\n", n1, n2);
xorswap(n1, n2);
printf("After xorswap() n1=%d, n2=%d\n", n1, n2);
return 0;
}
```

## Set other than 0 to 1

Set all values other than 0 to 1.

```<<macro_clamptoone.c>>=
#include <stdio.h>
#define clamptoone(value) (!!(value))
int main(void)
{
int n;
for(n=0; n<4; n++)
{
printf("n = %d clamped = %d\n",n,clamptoone(n));
}
return 0;
}
```