Problema con il mio macro morsetto
Domanda
Ho un problema con il mio macro morsetto, quando quando il mio valore è superiore a 10 e la mia è alta più di 17 smette di funzionare. Qualche idea?
#define CLAMP(value, low, high) (((value)<(low))?(low):(((value)>(high))?(high):(value)))
Soluzione
Io suggerirei di usare un modo più sicuro di una macro:
template <typename T> T CLAMP(const T& value, const T& low, const T& high)
{
return value < low ? low : (value > high ? high : value);
}
Altri suggerimenti
La macro va bene. Se si passa in un high
che è meno low
, vedrete i risultati strani, ma questo è improbabile che sia la causa.
Il risultato più probabile è che si sta passando in un'espressione che non ha effetti collaterali, come ad esempio utilizzando l'operatore ++
o chiamando una funzione. Se si dispone di un'espressione che ha effetti collaterali, poi a causa del modo in cui funziona sostituzione di macro, gli effetti collaterali possono accadere più volte. Ad esempio:
CLAMP(x++, low, high) // expands to:
(x++ < low) ? low : ((x++ > high) ? high : x++);
x++
viene valutato più volte, che non è sicuramente quello che si vuole (è un comportamento indefinito, a causa della mancanza di un punto di sequenza).
suggerirei riscrivere la macro come un modello:
template <typename T> T CLAMP(T value, T low, T high)
{
return (value < low) ? low : ((value > high) ? high : value);
}
Utilizzo di una funzione di modello come già suggerito è una soluzione migliore.
In ogni caso, se hai questo tipo di problema (entrambi con una macro o una funzione) si dovrebbe semplificare l'espressione; guardare a questo pseudocodice:
max(a,b): a>b ? a : b
min(a,b): a<b ? a : b
clamp(x,lo,hi): min( hi, max(lo,x) )
Si può anche rendere una funzione inline
quindi sarà come una macro, ma più sicura.