Pregunta

Tengo un problema con mi macro abrazadera, cuando cuando mi valor es más de 10 y mi alta es más del 17 deja de funcionar. Alguna idea?

#define CLAMP(value, low, high) (((value)<(low))?(low):(((value)>(high))?(high):(value)))
¿Fue útil?

Solución

Se recomienda usar una manera más segura que una macro:

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

Otros consejos

La macro está muy bien. Si pasa en un high que es menor que low, verá resultados extraños, pero eso es poco probable que sea la causa.

El resultado más probable es que estás pasando en una expresión que tiene efectos secundarios, tales como el uso del operador ++ o llamar a una función. Si usted tiene una expresión que tiene efectos secundarios, a continuación, por la forma en que la sustitución macro funciona, los efectos secundarios pueden ocurrir varias veces. Por ejemplo:

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

x++ se evaluaron varias veces, lo que definitivamente no es lo que quiere (que es un comportamiento indefinido, debido a la falta de un punto de secuencia).

Yo te sugeriría que volver a escribir la macro como una plantilla:

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

El uso de una función de plantilla como ya se ha sugerido una solución mejor.

De todos modos, si va a tener este tipo de problemas (ambos con una macro o una función) que debe simplificar su expresión; mira este pseudocódigo:

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

También puede hacer que sea una función inline por lo que será como una macro pero más seguro.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top