mBedLab Learning
779 subscribers
62 photos
6 videos
4 files
42 links
بحث و گفتگو در:
.
@mBedLab_Discussion
Download Telegram
#قانون 1.2 MISRA C - از افزونه‌های زبان C استفاده نکنیم!

○ گروه: #محیط_استاندارد_C
○ دسته‌بندی: #توصیه_شده
○ اعمال برای: C90, C99, C11

یکی از نکات مهم در برنامه‌نویسی به زبان C، پرهیز از استفاده از افزونه‌های (Extensions) خاص کامپایلرهاست. چرا؟

برنامه‌ای که به این افزونه‌ها وابسته باشد، ممکن است به راحتی روی کامپایلرهای مختلف یا سیستم‌عامل‌های گوناگون اجرا نشود (مشکل Portable بودن). استاندارد زبان C از کامپایلرها می‌خواهد که افزونه‌های خود را مستند کنند، اما این مستندات همیشه کامل نیستند و ممکن است رفتار افزونه در شرایط خاص را به طور دقیق شرح ندهند.

راه حل:
○ تا حد امکان از افزونه‌ها استفاده نکنید.
○ اگر مجبور به استفاده از افزونه‌ای هستید، دلیل آن را در مستندات پروژه خود ذکر کنید.
○ نحوه اطمینان از استفاده صحیح افزونه (مثلاً بررسی کامپایلر و پیام‌های خطا) را نیز مستند کنید.


نکته مهم: در سیستم‌های #Embedded (نهفته)، استفاده از افزونه‌ها گاهی ضروری است. اما دقت کنید که افزونه نباید رفتار برنامه‌های استاندارد C را تغییر دهد. برای مثال، اگر کامپایلری، ارزیابی کامل عملگرهای منطقی (مثل && و ||) را به عنوان یک افزونه پیاده‌سازی کند (در حالی که استاندارد C می‌گوید ارزیابی به محض مشخص شدن نتیجه متوقف شود)، این افزونه با استاندارد سازگار نیست، زیرا ممکن است باعث بروز اثر جانبی (Side Effect) های ناخواسته شود.

#برنامه_نویسی#استاندارد_MISRA
#Embedded

📍امبدلب به فارسی:
@mBedLabLearning

📍mBedLab in English:
@mBedLabLearningEN

📍mBedLab Türkçe'de
@mBedLabLearningTR
👍8👌1
#قانون 1.3 MISRA C - از رفتارهای تعریف‌نشده و نامشخص در C دوری کنیم!

○ گروه: #محیط_استاندارد_C
○ دسته‌بندی: #الزامی
○ اعمال برای: C90, C99, C11

یکی از مهم‌ترین قوانین در برنامه‌نویسی C، به‌خصوص در سیستم‌های حساس، پرهیز از رفتارهای «تعریف‌نشده» (Undefined Behavior) و «نامشخص» (Unspecified Behavior) است. استاندارد MISRA C هم بر این موضوع تأکید ویژه‌ای دارد.

رفتار تعریف‌نشده یعنی چی؟
رفتار تعریف‌نشده به وضعیتی در کد گفته می‌شه که استاندارد زبان C هیچ تضمینی برای نحوه عملکرد برنامه در اون حالت نمی‌ده. این یعنی کامپایلرها می‌تونن هر کاری انجام بدن، از کرش کردن برنامه گرفته تا تولید نتایج عجیب و غیرقابل پیش‌بینی. این اتفاقات ممکنه باعث بروز مشکلات جدی در سیستم‌های حیاتی بشه.


رفتار نامشخص چطور؟
رفتار نامشخص هم وضعیتیه که استاندارد C، رفتارهای مختلفی رو برای اون حالت مجاز دونسته، اما انتخاب نهایی به کامپایلر یا محیط اجرا سپرده شده. گرچه به اندازه رفتار تعریف‌نشده خطرناک نیست، اما می‌تونه باعث عدم قابلیت انتقال کد بین سیستم‌های مختلف بشه.


چرا این موضوع مهمه؟
فرض کنید برنامه‌ای نوشتید که در شرایط خاصی، دچار رفتار تعریف‌نشده می‌شه. این برنامه ممکنه روی سیستم شما به درستی کار کنه، اما روی یه سیستم دیگه یا حتی با یه کامپایلر دیگه، رفتاری کاملاً متفاوت و غیرمنتظره داشته باشه. این موضوع می‌تونه منجر به باگ‌های پنهان و مشکلات امنیتی جدی بشه.

MISRA C چی میگه؟
قانون 1.3 استاندارد MISRA C به طور خاص از وقوع هرگونه رفتار تعریف‌نشده و رفتارهای نامشخص «بحرانی» جلوگیری می‌کنه. این استاندارد یه لیست از این رفتارها رو در ضمیمه H خودش آورده و مشخص کرده که کدوم قوانین MISRA C از بروز هر کدوم جلوگیری می‌کنن.

یه مثال ساده:
دسترسی به عنصری خارج از محدوده یک آرایه، یه نمونه از رفتار تعریف‌نشده است.

#برنامه_نویسی#استاندارد_MISRA
#Embedded

📍امبدلب به فارسی:
@mBedLabLearning

📍mBedLab in English:
@mBedLabLearningEN

📍mBedLab Türkçe'de
@mBedLabLearningTR
👍4
#قانون 1.4 MISRA C - از ویژگی‌های جدید زبان C11 با احتیاط استفاده کنید!

○ گروه: #محیط_استاندارد_C
○ دسته‌بندی: #الزامی
○ اعمال برای: C11

در توسعه نرم‌افزارهای حساس به ایمنی و امنیت، رعایت استانداردها و پرهیز از رفتارهای غیرقابل پیش‌بینی بسیار حیاتی است. Rule 1.4 در استاندارد MISRA C به همین موضوع می‌پردازد و استفاده از ویژگی‌های "نوظهور" زبان را محدود می‌کند.

چرا این قانون مهم است؟
استفاده از این ویژگی‌ها می‌تواند منجر به رفتارهای undefined (تعریف‌نشده)، unspecified (نامشخص) یا implementation-defined (وابسته به پیاده‌سازی) شود. این یعنی کد شما ممکن است در کامپایلرها یا سیستم‌عامل‌های مختلف، رفتارهای متفاوتی داشته باشد و این امر می‌تواند خطرات جدی به همراه داشته باشد. حتی اگر رفتاری کاملاً تعریف‌شده باشد، ممکن است با انتظارات توسعه‌دهنده همخوانی نداشته باشد و منجر به باگ شود.

به طور خاص، این قانون استفاده از ویژگی‌های Annex K (رابط‌های بررسی مرزها) را به جز تعریف __STDC_WANT_LIB_EXT1__ به 0، ممنوع می‌کند.

راه حل چیست؟
اگر مجبور به استفاده از یک ویژگی نوظهور هستید، حتماً باید یک "انحراف" (deviation) ثبت کنید و رفتارهای نامطلوب احتمالی را شناسایی و اقدامات لازم برای جلوگیری از تأثیر آنها بر ایمنی و امنیت سیستم را مشخص کنید.

به عبارت دیگر، قبل از استفاده از هر ویژگی جدید، به دقت مستندات آن را بررسی کنید و از پیامدهای احتمالی آن آگاه باشید.


قوانین مرتبط:
قانون 1.3

#برنامه_نویسی#استاندارد_MISRA
#Embedded

📍امبدلب به فارسی:
@mBedLabLearning

📍mBedLab in English:
@mBedLabLearningEN

📍mBedLab Türkçe'de
@mBedLabLearningTR
🔥1🤩1
#قانون 1.5 MISRA C - دوری از ویژگی‌های منسوخ شده در کدنویسی C

○ گروه: #محیط_استاندارد_C
○ دسته‌بندی: #الزامی
○ اعمال برای: C99, C11

تصور کنید در حال نوشتن یک برنامه به زبان C هستید. آیا از تمام ویژگی‌های زبان و به‌روزرسانی‌های استاندارد آن آگاهید؟ استفاده از ویژگی‌های منسوخ شده (Obsolescent) می‌تواند منجر به مشکلات جدی در کد شما شود. به همین دلیل استاندارد MISRA قانونی را تحت عنوان قانون ۱.۵ وضع کرده است.

قانون MISRA 1.5 چیست؟
این قانون به ما می‌گوید که نباید از ویژگی‌های منسوخ شده زبان C استفاده کنیم. این ویژگی‌ها در بخش "جهت‌گیری‌های آینده زبان" و "جهت‌گیری‌های آینده کتابخانه" در استاندارد C (مانند C99 و C11) و همچنین در ضمیمه F آن ذکر شده‌اند.

چرا باید از این قانون پیروی کنیم؟
استاندارد C ویژگی‌ها را زمانی منسوخ اعلام می‌کند که:
○ جایگزین‌های ایمن‌تر یا بهتری برای آن‌ها وجود داشته باشد.
○ رفتار نامطلوبی از خود نشان دهند.

ویژگی‌هایی که در یک نسخه از استاندارد منسوخ اعلام می‌شوند، ممکن است در نسخه‌های بعدی به طور کامل حذف شوند. این موضوع می‌تواند باعث بروز خطا در کدهایی شود که از این ویژگی‌ها استفاده می‌کنند.

مزایای رعایت قانون MISRA 1.5:
○ کد پایدارتر و سازگارتر با نسخه‌های مختلف استاندارد C
○ کاهش احتمال بروز خطا و مشکلات ناشی از ویژگی‌های منسوخ شده
○ افزایش خوانایی و نگهداری کد

به طور خلاصه: با پیروی از قانون MISRA 1.5، کد خود را در برابر مشکلات احتمالی ناشی از استفاده از ویژگی‌های منسوخ شده ایمن کنید و به نوشتن کد استاندارد و قابل اعتماد پایبند باشید.

قوانین مرتبط:
قانون 1.1

#برنامه_نویسی#استاندارد_MISRA
#Embedded

📍امبدلب به فارسی:
@mBedLabLearning

📍mBedLab in English:
@mBedLabLearningEN

📍mBedLab Türkçe'de
@mBedLabLearningTR
👍3
#قانون 2.1 MISRA C - عدم وجود کد غیرقابل دسترس

○ گروه: #کدهای_استفاده_نشده
○ دسته‌بندی: #الزامی
○ اعمال برای: C90, C99, C11

کد غیرقابل دسترس، کدی است که تحت هیچ شرایطی در طول اجرای برنامه اجرا نمی‌شود. وجود این کد می‌تواند نشانه‌ای از خطای منطقی در برنامه باشد. اگرچه کامپایلر مجاز به حذف این کد است، اما این کار اجباری نیست. باقی ماندن کد غیرقابل دسترس باعث اتلاف منابع می‌شود، به عنوان مثال:
○ اشغال فضای حافظه
○ انتخاب دستورات پرش طولانی‌تر و کندتر توسط کامپایلر
○ جلوگیری از قرارگیری کل حلقه در حافظه کش دستورالعمل

دلایل اهمیت این قانون:
○ بهبود خوانایی و نگهداری کد
حذف کد غیرقابل دسترس، کد را تمیزتر و درک آن را آسان‌تر می‌کند.

○ بهینه‌سازی عملکرد
حذف کد غیرضروری باعث کاهش حجم کد و بهبود عملکرد برنامه می‌شود.

○ جلوگیری از خطاهای احتمالی
وجود کد غیرقابل دسترس می‌تواند نشانه‌ای از خطاهای منطقی باشد که ممکن است در آینده مشکل‌ساز شوند.


موارد خاص:
گاهی اوقات برای مدیریت موارد استثنایی، کدی درج می‌شود که به ظاهر غیرقابل دسترس است. به عنوان مثال، در دستور switch که تمام مقادیر ممکن عبارت کنترلی توسط case ها پوشش داده شده‌اند، طبق قانون 16.4 باید یک default وجود داشته باشد. هدف از default، گرفتن مقادیری است که به طور معمول نباید رخ دهند، اما ممکن است در نتیجه موارد زیر ایجاد شده باشند:
○ رفتار تعریف نشده در برنامه
○ خرابی سخت‌افزار پردازنده

اگر کامپایلر بتواند ثابت کند که یک default غیرقابل دسترس است، ممکن است آن را حذف کند. برای جلوگیری از این اتفاق و حفظ عملکرد دفاعی کد، می‌توان از دسترسی volatile استفاده کرد. با استفاده از volatile، کامپایلر مجبور می‌شود فرض کند که عبارت کنترلی می‌تواند هر مقداری را بگیرد.

مثال:
enum light { red, amber, red_amber, green };
enum light next_light ( enum light c )
{
enum light res;
switch ( c )
{
case red:
res = red_amber;
break;
case red_amber:
res = green;
break;
case green:
res = amber;
break;
case amber:
res = red;
break;
default:
{
error_handler ( );
break;
}
}
return res;
res = c; // غیر منطبق - این دستور قطعا غیرقابل دسترس است
}


در مثال بالا، دستور ;res = c بعد از ;return res قرار گرفته و هرگز اجرا نخواهد شد، بنابراین مصداق کد غیرقابل دسترس است و باید حذف شود.

نکته: کدی که توسط دستورات پیش‌پردازنده به صورت شرطی حذف شده است، مشمول این قانون نمی‌شود.


قوانین مرتبط:
○ قانون 14.3
○ قانون 16.4


#برنامه_نویسی#استاندارد_MISRA
#Embedded

📍امبدلب به فارسی:
@mBedLabLearning

📍mBedLab in English:
@mBedLabLearningEN

📍mBedLab Türkçe'de
@mBedLabLearningTR
👍1👌1
#قانون 2.2 MISRA C - اجتناب از کدهای مرده

○ گروه: #کدهای_استفاده_نشده
○ دسته‌بندی: #الزامی
○ اعمال برای: C90, C99, C11

قاعده 2.2 استاندارد MISRA بیان می‌کند که پروژه نباید حاوی کد مرده باشد. کد مرده به هر عملیاتی گفته می‌شود که اجرا می‌شود اما حذف آن تأثیری بر رفتار برنامه ندارد. وجود کد مرده می‌تواند نشان دهنده خطا در منطق برنامه باشد و باعث سردرگمی شود.

این قاعده در استانداردهای ایمنی مانند IEC 61508، ISO 26262 و DO-178C نیز مورد توجه قرار گرفته است.

نمونه‌های کد مرده:
○ استفاده از متغیری که مقدار آن بعداً خوانده نمی‌شود.
○ استفاده از عملگری که نتیجه آن استفاده نمی‌شود.
○ فراخوانی تابعی که هیچ تأثیری بر رفتار برنامه ندارد.

استثنائات:
○ تبدیل صریح به نوع void
این عمل نشان می‌دهد که مقدار مورد نظر عمداً استفاده نمی‌شود و خود به تنهایی کد مرده محسوب نمی‌شود.

○ عملگر تبدیل صریح (cast operator) که نتیجه آن استفاده می‌شود، کد مرده نیست.

اهمیت رعایت این قاعده
○ بهبود کیفیت کد
حذف کد مرده باعث کاهش حجم کد، بهبود خوانایی و نگهداری آن می‌شود.

○ کاهش خطاها
وجود کد مرده می‌تواند نشانه‌ای از خطاهای منطقی در برنامه باشد. حذف این کدها به بهبود پایداری و قابلیت اطمینان نرم‌افزار کمک می‌کند.

○ افزایش کارایی
حذف کد مرده می‌تواند به بهبود عملکرد برنامه کمک کند.


مثال:

extern volatile uint16_t v;
extern char *p; 

void f ( void )
{
uint16_t  x;
( void ) v;
( int32_t ) v;
v >> 3;
x = 3;
*p++;
( *p )++;
}


خطاهای موجود در مثال:
‏○ (int32_t) v: تبدیل نوع (cast) به int32_t انجام می‌شود اما نتیجه استفاده نمی‌شود.
‏○ v >> 3: عملگر شیفت راست (<<) اجرا می‌شود اما نتیجه استفاده نمی‌شود.
‏○ x = 3: مقداردهی به متغیر x انجام می‌شود اما مقدار آن در ادامه استفاده نمی‌شود.
‏○ p++*: عملگر اشاره‌گری (*) اجرا می‌شود اما نتیجه آن استفاده نمی‌شود.

نکات مهم
○ کد غیرقابل دسترس (Unreachable Code) کد مرده نیست، زیرا هرگز اجرا نمی‌شود.
○ عملیات مقداردهی اولیه (Initialization) متفاوت از عملیات انتساب (Assignment) است و کد مرده محسوب نمی‌شود.
○ برخی از عملیات‌های زبان (مانند دستورات اسمبلی) ممکن است همیشه تأثیر بر رفتار برنامه داشته باشند و کد مرده محسوب نشوند.

قوانین مرتبط:
○ قانون 17.7

#برنامه_نویسی#استاندارد_MISRA
#Embedded

📍امبدلب به فارسی:
@mBedLabLearning

📍mBedLab in English:
@mBedLabLearningEN

📍mBedLab Türkçe'de
@mBedLabLearningTR
2👍1🤩1