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)))
È stato utile?

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.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top