سؤال
#ifndef MACROS_NULLCHECK_H_
#define MACROS_NULLCHECK_H_
#include <assert.h>
#define NULLCHECK(x) assert(x != (void *) 0);
#endif
إذا استخدمت النمط أعلاه كقالب للإعلان عن وحدات الماكرو، فما هي الشروط التي ستكون لديك؟
المحلول
ضع قوسين حول الوسيطة (يمنع حدوث مشاكل عند تمرير التعبيرات)
لا تضع؛في النهاية (سيكون الاستخدام أكثر طبيعية)
#define NULLCHECK(x) يؤكد((x) != (void*)0)
نصائح أخرى
وبصفة عامة، يجب عليك دائما وضع الحجج الكلي بين قوسين في التوسع، أي في الحالة الخاصة بك
assert((x) != (void*) 0)
وهذا هو لأنه إذا لم تقم بعد ذلك أي تعبيرات (بدلا من المتغيرات البسيطة) التي تمر مايو خبط التوسع متغير.
وأود أن أقترح أيضا أنك لا تضع فاصلة منقوطة في نهاية تعريف الكلي، بحيث يكون لديك أن نسميها مثل
NULLCHECK(pSomething);
والتي تبدو أكثر عدلا C-مثل وبما يتفق مع بقية التعليمات البرمجية.
وتغيير واحد وأنا قد جعل سيكون للتعليق على #endif
الختام:
#endif // MACROS_NULLCHECK_H_
ويجعل من الاسهل لفهم ما الذي يقوم به #endif
هناك عندما يحصل على ملف أطول من الشاشة.
وبعض الممارسات الكلي جيدة من CERT C آمن الترميز ويكي :
<اقتباس فقرة> وPRE00-C. وحدات الماكرو-مثل وظيفة أفضل المضمنة أو ثابتة وظائف ل
PRE01-C. استخدام الأقواس في وحدات الماكرو حول أسماء المعلمات
PRE02-C. يجب قوسين قوائم الاستبدال الكلي
PRE03-C. تفضل typedefs لتعرف لأنواع ترميز
PRE10-C. التفاف وحدات الماكرو متعددة بيان في افعل حين حلقة
PRE11-C. لا تستنتج بيان تعريف الماكرو واحد بفاصلة منقوطة
PRE31-C. لم تحتج على ماكرو غير آمنة مع الحجج التي تحتوي على الاحالة، الزيادة، التناقص، والوصول متقلبة، أو استدعاء دالة
PRE32-C. لا تستخدم توجيهات المعالج داخل الحجج الكلية
تبدو جيدة. انها نمط I استخدام الكثير.
لفرض ;
، استخدم
#define NULLCHECK(x) do { assert((X)); } while (0)