في سي وحدات الماكرو، يجب أن يفضل المرء القيام به {...} بينما (0،0) أكثر من {...} بينما (0)؟

StackOverflow https://stackoverflow.com/questions/1853723

سؤال

قام العميل مؤخرا بتحليل ثابت لأصحاب العمل الخاص بي CodeBase وقدم لنا النتائج. وكان من بين بقع مفيدة طلب تغيير الشهير do { ... } while(0) ماكرو إلى do { ... } while(0,0). وبعد أنا أفهم ما يفعله التصحيح (باستخدام مشغل التسلسل إلى إرجاع تقييم لقيمة الثانية "0"، لذلك التأثير هو نفسه) ولكن ليس من الواضح لماذا يفضلون النموذج الثاني على النموذج الأول.

هل هناك سبب شرعي، يجب أن يفضل المرء الشكل الثاني من الماكرو، أو هو التحليل الثابت لعملائنا محورا بشكل مفرط؟

هل كانت مفيدة؟

المحلول

حسنا، سأذهب للحصول على إجابة:

هل هناك سبب مشروعين يجب أن يفضل المرء الشكل الثاني من الماكرو ...؟

لا، لا يوجد سبب مشروع. كلاهما يقيم دائما إلى FALSE، وربما يحول أي مترجم لائق من المحول البرمجي الثاني إلى الأول في الجمعية على أي حال. إذا كان هناك أي سبب يجب أن تكون غير صالحة في بعض الحالات، كان C حوالي فترة طويلة بما يكفي لهذا السبب الذي يجب اكتشافه بمقدار أكبر من I.

إذا كنت ترغب في صنع التعليمات البرمجية الخاصة بك عيون البومة فيك، استخدم while(0,0). وبعد خلاف ذلك، استخدم ما يستخدمه بقية العالم البرمجة C وأخبر عن أداة التحليل الثابت للعميل لتقييدها.

نصائح أخرى

مجرد تخمين لماذا قد يقترحون استخدام

do { ... } while(0,0)

على

do { ... } while(0)

على الرغم من عدم وجود فرق سلوك ويجب أن يكون هناك فرق تكلفة وقت التشغيل بين الاثنين.

تخميني هو أن أداة التحليل الثابت تشكو من while حلقة يجري تسيطر عليها ثابتة في حالة أبسط ولا 0,0 يستخدم. من المحتمل أن يكون اقتراح العميل فقط حتى لا يحصل على مجموعة من الإيجابيات الخاطئة من الأداة.

على سبيل المثال، صادفت في بعض الأحيان المواقف التي أريد أن أحصل عليها بيان مشروط يسيطر عليها ثابت، لكن المحول البرمجي سيعقد مع تحذير من تعبير شرطي تقييم ثابت. ثم لا بد لي من القفز من خلال بعض الأطواق للحصول على المترجم لوقف الشكوى (لأنني لا أحب تحذيرات زائفة).

اقتراح عميلك هو أحد الأطواق التي اعتدت عليها هادئة أن التحذير، رغم أنه في حالتي لم يكن سيطر while حلقة، كان التعامل مع تأكيد "فشل دائما". في بعض الأحيان، سآخذ مساحة من التعليمات البرمجية التي يجب ألا تنفذ أبدا (ربما الحالة الافتراضية للمفتاح). في هذه الحالة، قد يكون لدي تأكيد فشل دائما مع بعض الرسالة:

assert( !"We should have never gotten here, dammit...");

ولكن،، فإن مترجم واحد على الأقل أستخدم مشكلات تحذير حول التعبير دائما تقييم FALSE. ومع ذلك، إذا قمت بتغييره إلى:

assert( ("We should have never gotten here, dammit...", 0));

تحذير يذهب بعيدا، والجميع سعيد. أنا أظن أنه حتى أداة التحليل الثابت للعميل سيكون أيضا. لاحظ أنني أخفي عموما هذا القليل من هوب القفز وراء ماكرو مثل:

#define ASSERT_FAIL( x) assert( ((x), 0))

قد يكون من الجيد أن نكون قادرين على إخبار بائع الأدوات بإصلاح المشكلة، ولكن قد تكون هناك حالات مشروعة حيث يرغبون في تشخيص حلقة يتم التحكم فيها بواسطة تعبير منطقي ثابت. ناهيك عن حقيقة أنه حتى لو كنت تقنع بائع أداة لإجراء مثل هذا التغيير، لا يساعدك ذلك في العام المقبل أو حتى يستغرق الأمر فعليا للحصول على إصلاح.

استخدام while(0,0) يمنع برنامج Microsoft Compiler من إنشاء تحذير حول الحالة وهو ثابت (تحذير C4127).

عند تمكين هذا التحذير (على سبيل المثال مع / W4 أو / Wall)، يمكن إيقاف تشغيله على أساس كل حالة على حدة مع هذه الخدعة الصغيرة لطيفة (رؤية هذا الموضوع الآخر).

تحرير: منذ Visual Studio 2017 15.3، while(0) لا تنبعث من التحذيرات بعد الآن (راجع مشروط ثابت). يمكنك التخلص من الخاص بك (0,0) !

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