سؤال
لدي مشكلة في ماكرو المشبك الخاص بي ، عندما تكون قيمتي أكثر من 10 سنوات ، وتتوقف عن أعلى 17 عامًا ، فإنها تتوقف عن العمل. اي فكرة؟
#define CLAMP(value, low, high) (((value)<(low))?(low):(((value)>(high))?(high):(value)))
المحلول
أود أن أقترح استخدام طريقة أكثر أمانًا من الماكرو:
template <typename T> T CLAMP(const T& value, const T& low, const T& high)
{
return value < low ? low : (value > high ? high : value);
}
نصائح أخرى
الماكرو الخاص بك بخير. إذا مررت في high
هذا أقل من low
, ، سترى نتائج غريبة ، لكن من غير المحتمل أن يكون هذا هو السبب.
النتيجة الأكثر ترجيحًا هي أنك تمر في تعبير له آثار جانبية ، مثل استخدام ++
عامل أو استدعاء وظيفة. إذا كان لديك تعبير له آثار جانبية ، فمن بسبب الطريقة التي يعمل بها استبدال الماكرو ، يمكن أن تحدث الآثار الجانبية عدة مرات. فمثلا:
CLAMP(x++, low, high) // expands to:
(x++ < low) ? low : ((x++ > high) ? high : x++);
x++
يتم تقييمها عدة مرات ، وهو بالتأكيد ليس ما تريده (إنه سلوك غير محدد ، بسبب عدم وجود نقطة تسلسل).
أود أن أقترح إعادة كتابة الماكرو كقالب:
template <typename T> T CLAMP(T value, T low, T high)
{
return (value < low) ? low : ((value > high) ? high : value);
}
استخدام وظيفة قالب كما هو مقترح بالفعل هو حل أفضل.
على أي حال ، إذا كنت تواجه هذا النوع من المشكلات (سواء مع ماكرو أو وظيفة) ، فيجب عليك تبسيط تعبيرك ؛ انظر إلى هذا الرمز الكاذب:
max(a,b): a>b ? a : b
min(a,b): a<b ? a : b
clamp(x,lo,hi): min( hi, max(lo,x) )
يمكنك أيضًا جعلها inline
وظيفة لذلك سيكون مثل الماكرو ولكن أكثر أمانًا.