سؤال

لدي مشكلة في ماكرو المشبك الخاص بي ، عندما تكون قيمتي أكثر من 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 وظيفة لذلك سيكون مثل الماكرو ولكن أكثر أمانًا.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top