问题
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)))
回答1:
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);
}
回答2:
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);
}
回答3:
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) )
回答4:
You can also make it an inline
function so it will be like a macro but safer.
来源:https://stackoverflow.com/questions/4100657/problem-with-my-clamp-macro