نگاهی به توسعه و گسترش پیشپردازنده زبان C برای افزایش کارایی و راحتی کدنویسی — Fun Extending the C Preprocessor
خلاصه
این مقاله به بررسی ایدههای جالب توسعه پیشپردازنده C (CPP) در یک کامپایلر شخصی میپردازد. نویسنده با افزودن قابلیتهای بومی مانند چاپ دیباگ، نگاشت آرایهها و شمارش آرگومانهای متغیر، نشان میدهد که چطور میتوان از ترفندهای کثیف و پیچیده پیشپردازنده استاندارد خلاص شد.
بر خلاف تصور رایج بسیاری از برنامهنویسان، پیشپردازنده زبان C یا همان CPP صرفاً یک ابزار ترجمه متن به متن نیست؛ بلکه وظیفه ترجمه منبع به توکنهای C را بر عهده دارد. نویسنده که در حال توسعه یک کامپایلر، مفسر و REPL شخصی برای نسخه C2Y است، نگاهی داشته به روشهایی که میتوان پیشپردازنده را با افزودن امکانات جدید کاربردیتر و جذابتر کرد.
چرا پیشپردازنده استاندارد گاهی آزاردهنده است؟
برای انجام کارهای نسبتاً پیشرفته در پیشپردازنده C، توسعهدهندگان معمولاً مجبور به استفاده از ترفندهای پیچیده و اصطلاحاً «جادوی سیاه» میشوند. مواردی مثل پیادهسازی بازگشتی برای اعمال یک ماکرو روی فهرستی از آرگومانها (مثل ترفندهای معروف CAT و NARG) کدهایی بسیار کثیف، خوانناپذیر و کند تولید میکنند؛ چرا که مکانیزم پیشپردازنده باید هر آرگومان را چندین بار اسکن و گسترش دهد.
افزونههای بومی برای کاهش پیچیدگی
برای حل این مشکلات، نویسنده چند ماکروی داخلی و مفید به پیشپردازنده خود اضافه کرده است:
- ماکروهای
__print()و__where(): ابزارهای مستقیم برای دیباگ کردن. دستور__print(...)آرگومانهای خود را گسترش داده و مستقیماً رویstderrچاپ میکند تا ببینید ماکرو دقیقا به چه چیزی تبدیل شده است. از طرف دیگر،__where()به شما نشان میدهد که یک ماکروی دردسرساز دقیقا در کجا تعریف شده است. - ماکروی
__map(): به جای نوشتن کدهای پیچیده و چندلایه برای شبیهسازی بازگشت و اعمال یک ماکرو روی لیستی از آرگومانها، این قابلیت به صورت بومی و در یک پیمایش خطی این کار را انجام میدهد. این یعنی هیچ محدودیتی برای تعداد آیتمها وجود ندارد و کد به شدت تمیزتر میشود. - ماکروی
__VA_COUNT__: استاندارد C23 با معرفی__VA_OPT__()کار با ماکروهای متغیر (Variadic) را راحتتر کرد، اما پیدا کردن تعداد آرگومانها همچنان نیازمند ترفندهای دستیNARGاست. با داشتن__VA_COUNT__به صورت بومی، شمارش آرگومانهای متغیر به سادگی و بدون دردسر انجام میشود.
نگاه جامعه هکرنیوز
بحثهای پیرامون این مقاله در هکرنیوز نکات جالبی را روشن کرد. برخی کاربران اشاره کردند که ساختارهایی مثل دو مرحلهای CAT یا همان NARG چیزهایی هستند که به محض نیاز به پیشپردازش غیربدیهی، ناچار به بازآفرینیشان میشوید. همچنین اشاره شد که اگرچه کتابخانههایی مثل map-macro وجود دارند که بدون دستکاری کامپایلر MAP را فراهم میکنند، اما افزودن قابلیتهایی مثل __COUNTER__ (که قرار است به C29 اضافه شود) یا __VA_COUNT__ به استاندارد زبان، زندگی را برای توسعهدهندگان بسیار سادهتر خواهد کرد. عدهای نیز قابلیت مقایسه رشتهها در دستورات شرطی #if را از آرزوهای بزرگ خود دانستند.
چرا این موضوع برای مهندسان نرمافزار اهمیت دارد؟
متاپراگرمینگ در C همیشه به دلیل محدودیتهای تاریخی پیشپردازنده با چالش روبهرو بوده است. این مقاله نشان میدهد که ابزارهای ما چقدر میتوانند با تغییرات کوچک اما هوشمندانه در لایه پیشپردازنده، از کدهای پیچیده و غیرقابلنگهداری پاکسازی شوند و تجربه توسعه نرمافزار را بهبود ببخشند.
این مطلب بهصورت کاملاً خودکار و با هوش مصنوعی از مقالهٔ اصلی و بحث هکرنیوز تهیه شده و ممکن است خطا داشته باشد. حقوق مطلب اصلی متعلق به نویسندهٔ آن است. قوانین و گزارش مشکل