Question

I have a problem with my clamp macro, when when my value is over 10 and my high is over 17 it stops working. Any idea?

#define CLAMP(value, low, high) (((value)<(low))?(low):(((value)>(high))?(high):(value)))
Was it helpful?

Solution

I would suggest using a safer way than a macro:

template <typename T> T CLAMP(const T& value, const T& low, const T& high) 
{
  return value < low ? low : (value > high ? high : value); 
}

OTHER TIPS

Your macro is fine. If you pass in a high that is less than low, you'll see strange results, but that's unlikely to be the cause.

The most likely result is that you're passing in an expression that has side effects, such as using the ++ operator or calling a function. If you have an expression that has side effects, then because of the way that macro substitution works, the side effects could happen multiple times. For example:

CLAMP(x++, low, high)  // expands to:
(x++ < low) ? low : ((x++ > high) ? high : x++);

x++ gets evaluated multiple times, which is definitely not what you want (it's undefined behavior, due to the lack of a sequence point).

I'd suggest rewriting the macro as a template:

template <typename T> T CLAMP(T value, T low, T high)
{
    return (value < low) ? low : ((value > high) ? high : value);
}

Using a template function as already suggested is a better solution.

Anyway, if you're having this kind of problem (both with a macro or a function) you should simplify your expression; look at this pseudocode:

max(a,b): a>b ? a : b
min(a,b): a<b ? a : b
clamp(x,lo,hi): min( hi, max(lo,x) )

You can also make it an inline function so it will be like a macro but safer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top