روزبه شریف‌نسب
روزبه شریف‌نسب
خواندن ۲ دقیقه·۴ سال پیش

فعال کردن warning‌ها در gcc

وارنینگ‌ها اصلا چی هستند؟

زمانی که برنامه‌مون رو کامپایل می‌کنیم، کامپایلر (مثلا gcc یا mingw یا clang یا ...) میاد برنامه رو می‌خونه و از روش فایل قابل اجرا (exe یا out) رو تولید می‌کنه. حالا در این بین، یه چیزایی رو می‌بینه که طبق قواعد زبان (سینتکس) مشکلی نداره و باعث ارور نمیشه، ولی به نظرش می‌رسه که کسی که چنین چیزی نوشته حواسش نبوده و احتمالا باعث مشکل می‌شه.

مثال بزنم. کد زیر رو در نظر بگیرید:

int main(){ int a; a++; return 0; }


به لحاظ سینتکس هیچ مشکلی نداره و کامپایل میشه. حتی اجرا هم میشه. ولی gcc حدس می‌زنه که وقتی شما متغیر a تعریف کردی و بهش مقدار ندادی، ++ کردنش عملا کار بی‌معنی‌ایه. چون اصلا نمی‌دونی چی توش هست که بخوای بخونیش و یکی بهش اضافه کنی.


حالا چه خوب بود که خود gcc چنین چیزی می‌نوشت برامون:

warning: ‘a’ is used uninitialized in this function [-Wuninitialized] 3 | a++;


یا مثلا اگر متغیر تعریف کنی و «فقط مقدار توش بریزی» ولی «چیزی ازش نخونی» می‌تونه نشون‌دهنده این باشه که اون متغیر هیچ فایده‌ای نداره برای روال برنامه چون هیچوقت از مقدارش استفاده نشده.

بازم تاکید میکنم که مشکل سینتکس نیست ولی «احتمالا برنامه نویس بی‌دقتی کرده».


روش فعال کردن در gcc

در حالت عادی کامپایلر این ارور‌ها رو برای ما نمی‌نویسه، یا اگر بنویسه یه تعداد خیلی خیلی کمی‌شون رو می‌نویسه. اما می‌تونیم با پاس دادن -Wall به کامپایلر، بهش بگیم که «همه اخطار‌ها رو نشون بده»

یعنی در زمان کامپایل کردن، به جای

gcc code.c

بیایم بنویسم

gcc -Wall code.c

(دقت کنید W بزرگه ولی all کوچکه)


نکات تکمیلی

  • برای g++ هم دقیقا به همین صورته روند.
  • این برخلاف اسمش «همه وارنینگ‌ها» رو فعال نمی‌کنه بلکه یه تعداد خوبیشونه. می‌تونید در کنار -Wextra استفاده کنید که تعداد بیشتری رو نشون بده.
  • گاهی برنامه‌نویس‌ها علاقه دارن که زمانی که برنامه وارنینگ داره اصلا کامپایل نشه و اصطلاحا «وارنینگ‌ها به عنوان خطای کامپایل در نظر گرفته بشن» برای اینکار می‌تونیم از -Werror استفاده کنیم. با اینکار دیگه نمی‌نویسه وارنینگ بلکه می‌نویسه error و تا رفع نکنیم کامپایل صورت نمی‌گیره.

all warnings being treated as errors

(رفتار پیش‌فرض اینه که کامپایل میشه صرفا وارنینگ هم چاپ میشه)

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

چرا؟ چون وارنینگ ها کامپایلر به کامپایلر و نسخه به نسخه متفاوت می‌شن. بنابراین ممکنه شما با gcc نسخه ۹ کامپایل کنید و تست کنید و همه چیز هم خوب باشه ولی بفرستید برای من ولی من که gcc نسخه ۱۰ دارم وارنینگ جدیدی بهش اضافه شده باشه و باعث بشه کد توی سیستم من کامپایل نشه در حالی که واقعا مشکلی نداره. (خودم برای کامپایل یه کد قدیمی به این مشکل خوردم!)

cccppgccwarning
همینجا بگم که روزبه شریف نسب درسته و نه شریف نصب یا شریفی نسب یا هرچیز غلط دیگه..
شاید از این پست‌ها خوشتان بیاید