رفتار تعریفنشده در C و C++: هیچکس نمیتونه کد درست بنویسه
خلاصهٔ کاملتر
نویسنده — یک برنامهنویس C++ با سابقه ۳۰ ساله — ادعایی جسورانه مطرح میکنه: هیچکس نمیتونه کد C یا C++ بدون رفتار تعریفنشده (UB) بنویسه. UB (Undefined Behavior) یعنی وقتی استاندارد زبان هیچ تضمینی نمیده که کد چطور رفتار میکنه — نه کرش میکنه، نه درست کار میکنه، نه هیچچیز مشخص دیگهای. به گفته نویسنده، استاندارد C23 بهتنهایی ۲۸۳ بار از کلمه «undefined» استفاده کرده.
یک تصور رایج اینه که UB فقط وقتی بهینهسازی کامپایلر روشنه خطرناکه. نویسنده این رو رد میکنه: UB یعنی کامپایلر اصلاً مجبور نیست برای اون حالت کدی تولید کنه، چون «این حالت نباید وجود داشته باشه». سختافزار هم از این قضیه مستثنی نیست.
نویسنده چند مثال غیرمنتظره ارائه میده. مثلاً صرف ساختن یک پوینتر (pointer) با الاینمنت اشتباه — حتی قبل از اینکه ازش استفاده بشه — UBه. یا تابع isxdigit() که یک int میگیره، نه char؛ اگه معماری شما char را signed در نظر بگیره و مقدار ورودی بزرگتر از ۱۲۷ باشه، مقدار منفی به تابع میرسه و میتونه باعث خوندن از حافظه تصادفی بشه:
int isxdigit(int c) {
if (c == EOF) {
return false;
}
return some_array[c];
}تبدیل float به int هم ظاهراً سادهست ولی پر از تلهست. اگه مقدار float از محدوده int خارج باشه یا غیر متناهی (infinite/NaN) باشه، نتیجه UBه. حتی اضافه کردن 1 به یک int علامتدار (signed) که ممکنه سرریز (overflow) کنه هم UBه.
int milliseconds(float seconds) {
int tmp = (int)(seconds * 1000.0); /* WRONG */
return tmp + 1; /* WRONG separately (signed overflow is UB) */
}نکته جالب دیگه اینه که memset کردن یک ساختار به صفر، تضمین نمیده که پوینترهای عضوش NULL بشن — چون استاندارد C تضمین نمیده که NULL لزوماً بیتپترن صفر داشته باشه.
نویسنده پیشنهاد میده که در ۲۰۲۶ استفاده از LLM برای بررسی کد C/C++ از نظر UB تبدیل به یک الزام حرفهای بشه. اون حتی با کمک LLM یک باگ نوشتن خارج از محدوده حافظه در پروژه OpenBSD پیدا کرد و پچش رو ارسال کرد. البته تأیید خروجی LLM هنوز به یک انسان متخصص نیاز داره.
نکات کلیدی:
- UB در C/C++ بسیار گستردهتر از چیزیه که اکثر برنامهنویسها فکر میکنن
- خاموش کردن بهینهسازی کامپایلر مشکل UB رو حل نمیکنه
- حتی عملیات ساده مثل تبدیل نوع (type casting) یا صدا زدن توابع استاندارد میتونن UB باشن
- استاندارد C23 بهتنهایی ۲۸۳ مورد رفتار تعریفنشده داره
- LLMها میتونن ابزار مفیدی برای شناسایی UB باشن، ولی تأیید نهایی همچنان به متخصص انسانی نیاز داره
- نوشتن C/C++ بدون نظارت ابزارهای خودکار در ۲۰۲۶ احتمالاً بیمسئولیتیه




