رفتن به مطلب
مرجع رسمی سی‌پلاس‌پلاس ایران

تمامی فعالیت ها

این جریان به طور خودکار بروزرسانی می شود     

  1. جدیدا
  2. mag77

    شما در محیط لینوکس، وقتی کیوت رو نصب می‌کنید برای استفاده از اون مخصوصاً ساخت (کامپایل، بیلد) و اجرای برنامه نیاز به یک سری ابزار‌ها و کتابخانه‌های پیش‌نیاز دارید که با دستورات زیر باید پکیج‌های مربوط به اون رو نصب کنید. sudo apt-get install build-essential sudo apt-get install mesa-common-dev حالا شما دستور منسوخ شده رو اجرا کردین که ظاهراً مشکلتون حل شده، دلیلش هم احتمالاً دو ابزار qt4-qmake (= 4:4.8.7+dfsg-17) و qt4-dev-tools در پکیج هستش که نسخه‌های به‌روز تر و بهترش در پکیج build-essential موجود هست.
  3. بررسی دیزاسمبلی x86 در لینوکس – کامپایلر gcc به منظور بررسی دیزاسمبلی کد منبع C در لینوکس که محتوای آن در تصویر 2 نمایش داده شد، ابتدا خروجی تولید شده توسط کامپایلر gcc برای معماری x86 را توسط دیباگر gdb مورد بررسی قرار خواهیم داد. همانطور که در تصویر 12 قابل مشاهده است، وقتی کامپایلر باینری را با فلگ -ggdb کامپایل می‌کند، به دلیل وجود اطلاعات دیباگ درون باینری، دیباگر gdb می‌تواند اطلاعات تکمیلی و کامل درباره ساختار درونی باینری ELF ما نمایش دهد. برنامه ای که در تصویر 12 برای دیباگ باینری مورد استفاده قرار گرفته است، GDB Dashboard است که علاوه بر کد منبع، کد دیزاسمبلی، اطلاعات مرتبط با پشته و رجیسترها و خروجی که توسط کدها در حال تولید است، نمایش می‌دهد. تصویر 12: خروجی دیزاسمبلی برنامه در محیط لینوکس در ادامه به منظور درک بهتر کدی که توسط gcc برای معماری x86 تولید شده است، خط به خط مورد بررسی و تحلیل قرار خواهیم داد تا با رفتار کامپایلر gcc در تولید کدهای اسمبلی آشنا شویم. همانطور که در تصویر 13 قابل نمایش است، وقتی دستورالعمل call فراخوانی می‌شود، مجدد آدرس دستورالعمل بعدی را درون پشته قرار خواهد داد. آدرسی که توسط call بر روی پشته قرار گرفته است، در تصویر 13 با رنگ قرمز قابل مشاهده است. تصویر 13: خروجی اجرای دستورالعمل call وقتی وارد تابع StructureAnalysis می‌شویم، در گام اول با Prologue تابع روبه‌رو خواهیم شد. در Prologue تابع StructureAnalysis بعد از اینکه فریم جدید تابع ایجاد می‌شود، مقدار 0x424 (1060 دسیمال) از مقدار جاری رجیستر ESP کم خواهد شد. این مقدار نشان می‌دهد که 1060 بایت برای ذخیره‌سازی متغییرهای درون این تابع رزرو خواهد شد. تصویر 14: دیزاسمبی مقداردهی اعضای Structure توسط GCC خروجی که توسط کامپایلر GCC تولید شده است، مشابه خروجی MSVC است. متغیرهای درون Struct با استفاده از آدرس پایه‌ای که درون رجیستر EBP قرار دارد، و همچنین آفست‌هایی که مشخص کننده اندازه متغیرها است، مقداردهی می‌شوند. برای کار با داده‌های اعشاری هم از دستورات fld و fstp استفاده شده است. در نهایت وقتی استراکچر مقداردهی اولیه شد، برای نمایش مقادیر آن‌ها به تابع printf عبور داده می‌شوند. تصویر 15: خروجی دیزاسمبلی تابع StructureAnalysis شایان ذکر است، در ابتدای هر تابع درون برنامه همانطور که در تصویر 15 و تصویر 16 قابل مشاهده است، یک تابع با نام __x86.get_pc_thunk.bx فراخوانی می‌شود. در تجزیه و تحلیل یک باینری لینوکس، تابع __x86.get_pc_thunk.bx معمولاً همراه با ثبت ebx برای محاسبه آدرس پایه یک بخش داده یا کد مستقل از موقعیت (PIC) استفاده می‌شود. هدف __x86.get_pc_thunk.bx این است که آدرس دستور بعدی را در رجیستر ebx بارگذاری کند. این امکان را فراهم می‌کند تا دستورات بعدی بتوانند از ebx به عنوان یک رجیستر پایه استفاده کنند تا به داده‌ها یا کدهای نسبت به موقعیت فعلی در حافظه دسترسی پیدا کنند. با استفاده از __x86.get_pc_thunk.bx و ebx، کدهای مستقل از موقعیت می‌توانند به گونه‌ای نوشته شوند که به آدرس مطلق کد یا داده وابسته نباشند. شایان ذکر است، پیاده‌سازی __x86.get_pc_thunk.bx ممکن است بسته به کامپایلر و توزیع لینوکس متفاوت باشد. این تابع معمولاً توسط کتابخانه‌های اجرایی کامپایلر یا کتابخانه C سیستم ارائه می‌شود. در تصویر 16، این موضوع قابل نمایش است. تصویر 16: نمایش فراخوانی __x86.get_pc_thunk.ax در ابتدای تابع main بررسی دیزاسمبلی x86 در لینوکس – کامپایلر clang خروجی که کامپایلر clang تولید می‌کند به مراتب از خروجی که توسط GCC و MSVC در مراحل قبلی تولید شده است، متفاوتر است. در ادامه خروجی نسخه 14 کامپایلر clang را برای برنامه‌ای که به زبان C نوشته شده بود، مورد بررسی قرار خواهیم داد. در تصویر 17، ساختار دیزاسمبلی تابع main قابل مشاهده است که توسط کامپایلر clang تولید شده است. یکی از مهم ترین تفاوت هایی که در خروجی تولید شده توسط کامپایلر clang نسبت به gcc و msvc وجود دارد، در شروع توابع است. خروجی که clang تولید می‌کند، بعد از ایجاد فریم برای تابع، ما یک دستور call خواهیم داشت. هنگامیکه این دستور call اجرا می‌شود، تازه بدنه اصلی تابع شروع به اجرا خواهد شد. تصویر 17: دیزاسمبلی کد تولید شده توسط clang همانطور که در تصویر 17 قابل مشاهده است، در ابتدای تابع یک call به یک لیبل با عنوان LAB_000112EA داریم که از ابتدای آن اجرای بدنه اصلی تابع شروع می‌شود. تفاوت بعدی که وجود دارد، Calling Convention مورد استفاده توسط کامپایلر clang است که نسبت به msvc و gcc تفاوت دارد. به عنوان مثال، در تصویر 18 اصول عبور پارامترها به تابع printf قابل مشاهده است. در خروجی دیزاسمبلی clang به جای PUSH شدن پارامترها از راست به سمت چپ درون پشته، در خروجی clang از رجیسترها برای عبور پارامترها به توابع C استفاده می‌شود. تصویر 18: نحوه عبور پارامترها به تابع با توجه بررسی خروجی کامپایلرهای GCC و MSVC و Clang در پردازش Structها در زبان سی تفاوت برجسته ای وجود نداشت. هر سه کامپایلر برای مقداردهی اعضای استراکچر از آدرس پایه ای استفاده کرده بودند که توسط رجیستر EBP مورد ارجاع قرار می‌گرفت. دو کامپایلر GCC و MSVC از یک اصول تقریبا مشابه‌ای دنباله روی می کردند، ولی clang به جای استفاده از Stack از رجیسترهای عمومی x86 برای عبور پارامترها به توابع استفاده می‌کرد. پایان.
  4. در تصویر 7، خروجی کپی مقادیر CC به درون آدرسی که توسط EDI مورد ارجاع قرار گرفته است، قابل نمایش است. تصویر 7: کپی مقدار CC به درون آدرس مورد ارجاع توسط EDI دستوراتی که در ادامه آورده شده‌اند، مربوط به فلگ GS کامپایلر هستند که مفهوم قناری در پشته را به درون طرح پشته اضافه می‌کند. ابتدا یک مقدار شبه رندوم که در ثابت __security_cookie قرار دارد توسط کامایلر بازیابی شده و در رجیستر EAX ذخیره می‌شود. سپس بر روی مقدار درون رجیستر EAX با مقدار درون EBP یک عملیات XOR انجام می‌شود و در نهایت، خروجی عملیات XOR در آدرس [ebp-4] ذخیره می‌شود. مقدار نهایی که در این آدرس قرار می‌گیرد، به منظور بررسی عدم تخریب حافظه Stack مورد بررسی قرار خواهد گرفت. در نهایت تابع CheckForDebuggerJustMyCode فراخوانی شده است که به دلیل فعال سازی فلگ JMC به کد اضافه می‌شود. در تصویر 8، خروجی دیزاسمبلی این تابع در حالت Release درون IDA Pro نمایش داده شده است. همانطور که قابل مشاهده است، بخش زیادی از کدهای دیزاسمبلی که در حالت Debug قابل مشاهده است، هنگامیکه باینری در مُد Release تولید می‌شود، آن اطلاعات اضافی وجود ندارد. تصویر 8: خروجی دیزاسمبلی باینری مُد Release درون IDA Pro با این حال، همانطور که در تصویر 9 نمایش داده شده است، بعد از اینکه ما یک Struct تعریف می‌کنیم، و اولین ممبر آن را مقداردهی می‌کنیم، دستور mov dword ptr آورده شده است. هنگامیکه در خروجی لیست دیزاسمبلی با dword رو به رو می‌شویم، به این معنا است که با یک متغیر 32 بیتی رو به رو هستیم. از آنجایی که اولین عضو Struct ما از نوع int بوده است، در اینجا عمل mov بر روی یک آدرس 32 بیتی صورت گرفته است. ولی در ادامه به جای o_structure در سطح اسمبلی کامپایلر از رجیستر ebp به منظور دسترسی به اعضای استراکچر Disassembly استفاده کرده است. مثلا در گام دوم، برای کپی مقدار اسکی 14h به درون عضو m_char از رجیستر ebp به همراه آفستی که آن عضو درون پشته قرار دارد، استفاده کرده است تا مقدار 14h را به درون آن منتقل کند. در ادامه همین مسئله مجدد رخ داده است و تنها اندازه آفست دستورالعمل mov تغییر کرده است. همچنین در نهایت به دلیل اینکه یک مقدار Floating-Point مورد استفاده قرار گرفته است، در سطح اسمبلی شاهد استفاده از رجیسترهای XMM به همراه دستور movss هستیم. هنگامیکه در معماری x86 با یک نوع داده float رو به رو هستیم، از دستورالعمل movss و dword ptr استفاده شده است، اما هنگامیکه با یک نوع داده double رو به رو هستیم، از دستورالعمل movsd و mmword ptr استفاده شده است. تصویر 9: مقداردهی اعضای Struct در زبان C در ادامه آرایه کاراکتری که درون Struct تعریف شده است، با استفاده از تابع strncpy مقداردهی شده است. همانطور که در تصویر 10 قابل مشاهده است، دستور mov esi, esp مقدار جاری پشته را در ثبات esi قرار می‌دهد. این دستور معمولاً برای ذخیره کردن مقدار پشته در یک ثبات استفاده می‌شود. در ادامه دستورالعمل push offset string "Milad" آدرس رشته "Milad" را در پشته قرار می‌دهد. این دستور برای پاس دادن آرگومان‌ها به توابع در Calling Convention زبان C استفاده می‌شود. در ادامه مجدد یک دستور push آورده شده است که این دستور مقدار 400 به صورت عددی را در پشته قرار می‌دهد. دستور lea eax, [ebp-40Ch] آدرس ebp-40C را در eax قرار می‌دهد. دستور lea برای محاسبه آدرس یک متغیر استفاده می‌شود. سپس مجدد مقدار درون این رجیستری با استفاده از دستور push eax در پشته قرار می‌دهد. در نهایت وقتی پارامترهای مورد نیاز strcpy_s به درون پشته کپی شد، این تابع فراخوانی می شود. تابع strcpy_s برای کپی کردن یک رشته به رشته دیگر استفاده می‌شود. دستورالعمل بعدی که فراخوانی شده است add esp, 0Ch مقدار 0Ch (12 در مبنای 16) را به esp اضافه می‌کند. این دستور برای تعیین موقعیت صحیح پشته پس از فراخوانی تابع استفاده می‌شود. در نهایت با فراخوانی دستورالعمل مقدار درون رجیستر esi و esp با دستورالعمل cmp مورد مقایسه قرار خواهند گرفت. این دستور برای بررسی صحت موقعیت پشته استفاده می‌شود. دستورالعمل نهایی که به دلیل فلگ RTC1 به باینری اضافه شده است، تابع __RTC_CheckEsp را فراخوانی می‌کند. این تابع برای بررسی صحت موقعیت پشته استفاده می‌شود. در کل، این کد اسمبلی یک رشته به نام "Milad" را با استفاده از تابع strcpy_s کپی می‌کند و سپس موقعیت پشته را بررسی می‌کند. در تصویر 10، خروجی همین ساختار را در IDA Pro قابل مشاهده است: تصویر 10: خروجی دیزاسمبلی باینری در مُد Release یکی از مهم‌ترین تفاوت‌هایی که در خروجی تولید شده توسط IDA Pro نسبت به خروجی تصویر 9 وجود دارد، مقداردهی تمامی اعضای استراکچر به صورت یکجا است. متغیرها با استفاده از آدرس پایه که توسط رجیستر esp مورد ارجاع قرار گرفته است، و آفست‌هایی که در تصویر 10 قابل مشاهده است، تمامی اعضای استراکچر مقداردهی اولیه شده‌اند. شایان ذکر است، قبل از اینکه تابع strcpy_s فراخوانی شود، پارامترهای آن درون پشته PUSH شده است. شایان ذکر است، دستور and esp, 0FFFFFFC0h اشاره‌گر به پشته یا ESP را تراز می‌کند و دستور sub esp, 440h فضایی برای متغیرهای محلی رزرو می‌کند. این مراحل تضمین می‌کنند که مدیریت صحیح پشته انجام شده و محیط یکنواختی برای اجرای تابع فراهم می‌کنند. سپس در ادامه تمامی این مقادیر با عبور به تابع printf نتیجه آن‌ها برای کاربر نمایش داده خواهند شد. تصویر 11: عبور مقادیر اعضای استراکچر به تابع printf
  5. مقدمه‌ای بر فهمایش دیزاسمبلی در این تحقیق تلاش بنده بر این بوده است که ساختار بلاک‌های اسمبلی که کامپایلر MSVC و GNU و Clang برای استراکچرها زبان C در پلتفرم x86 تولید می‌کنند، مورد بررسی قرار بدهم. شایان ذکر است، خروجی MSVC با استفاده IDA Pro در محیط ویندوز و خروجی GCC و Clang در محیط لینوکس با استفاده از Ghidra مورد بررسی قرار گرفته‌اند. استراکچری که دیزاسمبلی آن مورد بررسی قرار گرفته است، به شرح زیر است: تصویر 1: محتوای استراکچر مورد بررسی در تصویر 1، محتوای استراکچر نمایش داده شده است. این استراکچر شامل 6 عضو از انواع داده در زبان C می‌شود. در تصویر 2، نحوه استفاده از این استراکچر نمایش داده شده است. از قبیل اینکه چگونه اعضای این استراکچر که دارای نوع داده اشاره‌گر به کاراکتر هستند، مقداردهی و مورد فراخوانی قرار گرفته‌اند: تصویر 2: نحوه استفاده از استراکچر در زبان C بعد از اینکه برنامه بالا نوشته شد، برنامه بالا را با فلگ‌های زیر توسط MSVC کامپایل کردم. در جدول 1 فلگ‌های پیش‌فرض که در MSVC تنظیم شده بود، آورده شده است: Debug Configuration Compiler Flags: /JMC /permissive- /ifcOutput "x64\Debug\" /GS /W3 /Zc:wchar_t /ZI /Gm- /Od /sdl /Fd"x64\Debug\vc143.pdb" /Zc:inline /fp:precise /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /MDd /FC /Fa"x64\Debug\" /EHsc /nologo /Fo"x64\Debug\" /Fp"x64\Debug\Structs.pch" /diagnostics:column Release Configuration Compiler Flags: /permissive- /ifcOutput "x64\Release\" /GS /GL /W3 /Gy /Zc:wchar_t /Zi /Gm- /O2 /sdl /Fd"x64\Release\vc143.pdb" /Zc:inline /fp:precise /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /Gd /Oi /MD /FC /Fa"x64\Release\" /EHsc /nologo /Fo"x64\Release\" /Fp"x64\Release\Structs.pch" /diagnostics:column جدول 1: فلگ‌های MSVC برای کامپایل برنامه برخی از فلگ‌هایی که در مُد Debug و Release برای Visual Studio تعریف شده‌اند، در ادامه مورد تشریح قرار گرفته‌اند. این فلگ ها به صورت پیش فرض در مُدهای مختلف Visual Studio فعال هستند، با این حال فلگ‌های دیگر که به صورت سفارشی به منظور تاثیر آن‌ها بر روی خروجی دیزاسمبلی مورد بررسی قرار خواهند گرفت، به صورت مجزا تشریح خواهند شد: فلگ‌های فعال در مُد دیباگ: فلگ JMC: فلگ Just My Code برای ساده‌تر کردن دیباگ برنامه‌ها طراحی شده است و با تمرکز بر روی کد خود کاربر، کدهای مرتبط با سیستم و فریمورک را مخفی می‌کند. وقتی این ویژگی فعال است، پروسه دیباگ می‌تواند از کد غیرکاربری، مانند کتابخانه‌های سیستم یا فریمورک‌های شخص ثالث عبور کند و این امر باعث می‌شود که مراحل پیمایش و درک جریان کد آسان‌تر شود. به عنوان مثال، هنگامیکه در حال دیباگ برنامه با استفاده از رویکرد Step-In هستیم، وارد توابع سیستمی و کتابخانه‌های جانبی نخواهیم شد. این امر در نهایت موجب می‌شود، رویکرد دیباگ محدود به کدهایی شود که خود برنامه‌نویس نوشته است. فلگ Permissive: فلگ Permissive به منظور حفظ مطابقت با قواعد نحوی و استانداردهای برنامه‌نویسی CPP است. وقتی این فلگ را تنظیم می‌کنید، کامپایلر اصول Compatibility را نادیده خواهد گرفت، و تلاش بر این خواهد شد که طبق استانداردهای جاری مطابقت نحوی (Syntax Conformance) و مطابقت معنایی (Semantic Conformance) برنامه را مورد بررسی قرار بدهد. به عنوان مثال، این گزینه اگر فعال باشد امکان استفاده از توابعی مانند strcpy به ما داده نخواهد شد، و شخص برنامه‌نویس باید از strcpy_s اضافه کند که نسخه ایمن‌سازی شده تابع مذکور است. فلگ GS: فلگ GS به عنوان یک ویژگی امنیتی برای شناسایی برخی از آسیب‌پذیری‌های سرریز بافر استفاده می‌شود. وقتی فلگ GS فعال است، کامپایلر MSVC کد اضافی را به اجرایی تولید شده اضافه می‌کند تا در زمان اجرا بررسی‌هایی روی برخی از عملیات‌های بافر انجام دهد. فلگ GS به حفاظت در برابر سرریز بافرهای مبتنی بر Stack کمک می‌کند. این با افزودن یک کوکی امنیتی به نام Security Cookie به فریم Stack توابعی که از بافرهای لوکال استفاده می‌کنند، عمل می‌کند. این کوکی امنیتی به عنوان یک مقدار نگهبان عمل می‌کند و قبل از بازگشت تابع بررسی می‌شود تا اطمینان حاصل شود که فریم Stack دچار خرابی نشده است. این استفاده از فلگ GS در MSVC باعث ارائه یک لایه اضافی از امنیت برای شناسایی و کاهش آسیب‌پذیری‌های سرریز بافر می‌شود. فلگ ZI: فلگ Zi امکان تولید اطلاعات دیباگینگ را فراهم می‌کند. هنگام استفاده از این فلگ، کامپایلر اطلاعات اضافی را در فایل اجرایی قرار می‌دهد که پروسه دیباگ را بهبود می‌بخشد. فلگ Zi به کامپایلر دستور می‌دهد تا یک فایل PDB تولید کند که شامل سمبول‎ها و اطلاعات دیباگینگ درباره کد منبع است. این اطلاعات شامل نام‌های تابع، نام‌های متغیر، شماره خطوط و سایر جزئیاتی است که برای دیباگ و تجزیه و تحلیل برنامه در زمان اجرا مفید است. فایل PDB که با استفاده از فلگ Zi تولید می‌شود، می‌تواند توسط ابزارهای دیباگینگ مانند Visual Studio Debugger استفاده شود تا دیباگ ساده‌تری را فراهم کند. هنگامیکه یک باینری را در IDA Pro دیباگ می کنیم، اگر فایل PDB آن را به دیباگر بدهیم، خروجی با معناتری را به ما ارائه می‌دهد که صرفا آدرس‌های خالی نیستند. فلگ Od: این فلگ برای غیرفعال‌سازی بهینه‌سازی استفاده می‌شود و به کامپایلر دستور می‌دهد که در طول فرآیند کامپایل، تمام بهینه‌سازی‌ها را غیرفعال کند. زمانی که از فلگ Od استفاده می‌شود، کامپایلر کد اسمبلی بدون بهینه‌سازی تولید می‌کند که به کد منبع اصلی نزدیک است. این مورد در برخی حالت‌ها مفید است، مانند زمانی که برنامه خود را در حالت دیباگ قرار می‌دهید و می‌خواهید کد تولید شده به صورت دقیق با کد منبع اصلی همخوانی داشته باشد تا دیباگ و پیمایش کد آسان‌تر باشد. غیرفعال‌سازی بهینه‌سازی با استفاده از فلگ Od منجر به اجرای کد با سرعت کمتر نسبت به کدهای بهینه‌سازی شده با سایر فلگ‌های بهینه‌سازی مانند O1، O2 یا Ox شود. با این حال، برای اهداف دیباگ می‌تواند مفید باشد زیرا کد تولید شده آسان‌تر قابل فهم است. شایان ذکر است، به طور پیش‌فرض، زمانی که کد منبع را بدون مشخص کردن هیچ فلگ بهینه‌سازی کامپایل می‌کنید، کامپایلر فرض می‌کند Od استفاده شده و بهینه‌سازی را غیرفعال می‌کند. اگر می‌خواهید بهینه‌سازی را فعال کنید، باید یکی از فلگ‌های بهینه‌سازی مانند O1، O2 یا Ox را مشخص کنید تا سطوح مختلف بهینه‌سازی را فعال کنید. فلگ Zc:inline: فلگ Zc برای کامپایلر توابع inline را بر اساس استاندارد زبان CPP فعال یا غیرفعال می‌کند. در زبان CPP، کلیدواژه "inline" برای نشان دادن به کامپایلر استفاده می‌شود که یک تابع باید در محل فراخوانی به صورت inline گسترش یابد، به جای اینکه به صورت یک تابع جداگانه فراخوانی شود. هنگامیکه این فلگ را استفاده می کنیم، تمامی توابعی که به صورت inline تعریف شده اند، در محل فراخوانی خود expand خواهند شد و پرشی به محلی دیگر از حافظه صورت نخواهد گرفت. در نتیجه به دلیل عدم استفاده از حافظه Stack و دستورات مرتبط با کار با پشته سرعت اجرای برنامه بهینه خواهد شد. اگر این فلگ در نظر گرفته نشده باشد، حتی با وجود واژه inline در امضا توابع، کامپایلر توابع مذکور را به صورت inline مورد پردازش قرار نخواهد داد. فلگ fp:precise: فلگ fp:precise در کامپایلر MSVC مدل اعداد ممیز شناور را کنترل می‌کند. به طور پیش فرض، MSVC از گزینه /fp:precise استفاده می‌کند که به معنای تولید کد توسط کامپایلری است که به طور دقیق از استاندارد IEEE 754 پیروی می‌کند. این گزینه کنترل دقیقی را برای حالت گردکردن فراهم می‌کند و تضمین می‌کند که نتایج میانی با دقت کامل محاسبه می‌شوند. فلگ /fp:precise به ویژه در مواردی که نیاز به رعایت دقیق استاندارد IEEE 754 وجود دارد، مانند برنامه‌های علمی یا محاسبات عددی که دقت و سازگاری بسیار مهم است، مفید است. این فلگ می‌تواند سازگاری و قابلیت حمل‌ونقل کدی که بر روی رفتار خاص اعداد ممیز شناور را بستگی دارد، حفظ کند. بنابراین، در مواردی که عملکرد اولویت اصلی است و رعایت دقیق استاندارد لازم نیست، می‌توانید از مدل‌های دیگر اعداد ممیز شناور ارائه شده توسط MSVC مانند /fp:fast یا /fp:strict استفاده کنید. فلگ Zc:forScope: این فلگ قوانین استاندارد CPP را برای متغیرهای حلقه for فعال می‌کند. به طور پیش فرض، MSVC از قوانین قدیمی استفاده می‌کند که متغیر حلقه for در خارج از محدوده حلقه قابل مشاهده است. این موضوع می‌تواند منجر به مشکلات و رفتارهای ناخواسته شود. زمانی که فلگ Zc:forScope فعال شود، قوانین MSVC برای متغیرهای حلقه for مطابق با استاندارد CPP اعمال می‌شود و قابلیت دید متغیر حلقه فقط در بدنه حلقه محدود می‌شود. فلگ RTC1: برای فعال کردن بررسی‌های خطا در زمان اجرا استفاده می‌شود. این فلگ مخفف "Run-Time Error Checks Level 1" می‌باشد. وقتی این فلگ فعال شود، کامپایلر کد اضافی را در برنامه قرار می‌دهد تا بررسی‌هایی در زمان اجرا برای انواع مختلف خطاها انجام دهد، مانند بررسی‌های سرریز بافر، متغیرهای نا‌مقداردهی شده و استفاده نادرست از اشاره‌گرها از جمله این خطاها در برنامه‌نویسی هستند. فعال کردن فلگ RTC1 می‌تواند به شناسایی و تشخیص خطاهای برنامه‌نویسی که ممکن است منجر به رفتار تعریف نشده یا خرابی در زمان اجرا شوند، کمک کند. این فلگ هزینه اضافی را به اجرای برنامه اضافه می‌کند، زیرا بررسی‌های زمان اجرا نیازمند کد و محاسبات اضافی هستند. با این حال، در مراحل توسعه و دیباگ، می‌تواند یک ابزار مفید باشد تا مشکلات احتمالی را در مراحل اولیه شناسایی و رفع کنید. فلگ Gd: این فلگ برای تعیین نحوه فراخوانی توابع C استفاده می‌شود. نحوه فراخوانی تعیین می‌کند که چگونه پارامترهای تابع منتقل می‌شوند و چگونه تابع با کد فراخواننده تعامل می‌کند. وقتی از پرچم /Gd استفاده می‌شود، نحوه فراخوانی پیش‌فرض را مشخص می‌کند که به عنوان نحوه فراخوانی cdecl شناخته می‌شود. در نحوه فراخوانی cdecl، پارامترهای تابع از راست به چپ روی Stack قرار می‌گیرند و فراخواننده مسئول پاکسازی Stack پس از بازگشت تابع است. این نحوه فراخوانی به طور معمول در برنامه‌نویسی به زبان C استفاده می‌شود. شایان ذکر است، به طور پیش‌فرض، MSVC از نحوه فراخوانی cdecl استفاده می‌کند، بنابراین استفاده از فلگ Gd ضروری نیست. با این حال، مشخص کردن صریح /Gd مطمئن می‌شود که نحوه فراخوانی پیش‌فرض استفاده می‌شود. فلگ MDd: فلگ MDd برای تنظیمات دیباگ و استفاده از کتابخانه‌های پیش‌فرض (CRT) استفاده می‌شود. این فلگ برای توسعه و دیباگ برنامه‌ها استفاده می‌شود و به شما امکان می‌دهد تا از امکانات دیباگ موجود در برنامه استفاده کنید. وقتی از فلگ MDd استفاده می‌کنید، برنامه شما با استفاده از کتابخانه‌های پیش‌فرض (CRT) که به صورت دیباگ شده هستند، کامپایل می‌شود. فلگ FC: فلگ FC برای تعیین نام فایل منبع در خروجی کامپایلر استفاده می‌شود. این فلگ با اضافه کردن مسیر کامل فایل منبع به خروجی کامپایلر، به تولید پیام‌های خطا و اخطار با اطلاعات بیشتر کمک می‌کند. هنگام استفاده از فلگ /FC، کامپایلر مسیر کامل فایل منبع را به همراه پیام خطا یا اخطار نمایش می‌دهد. این ویژگی مفید است زمانی که شما چندین فایل منبع در دایرکتوری‌های مختلف دارید، زیرا به شما امکان می‌دهد به سرعت مکان خطا یا اخطار را تشخیص دهید. فلگ FA: فلگ FA برای کنترل تولید کد اسمبلی در فرآیند کامپایل استفاده می‌شود. این فلگ به شما امکان می‌دهد نوع و فرمت کد اسمبلی تولید شده را مشخص کنید. فلگ FA چندین گزینه دارد که رفتار تولید کد اسمبلی را تعیین می‌کنند. فلگ FA در هنگام فرآیند کامپایل، یک فایل اسمبلی (.asm) همراه با فایل آبجکت (.obj) تولید می‌کند. فایل لیستینگ کد اسمبلی شامل کد اسمبلی تولید شده متناظر با کد منبع است. فلگ Fa این گزینه را به ما اجازه می‌دهد نام و مکان سفارشی برای فایل لیستینگ اسمبلی مشخص کنید. شایان ذکر است، فلگ FAs همزمان فایل لیستینگ کد اسمبلی (.asm) و فایل لیستینگ کد ماشین (.cod) را در هنگام کامپایل تولید می‌کند. فایل لیستینگ کد ماشین شامل نمایش شماره‌ای از دستورات ماشین به صورت هگزادسیمال است. فلگ EHsc: این فلگ برای تعیین مدل برخورد با اکسپشن‌ها در کد CPP استفاده می‌شود. این فلگ برای "Exception Handling (Standard C++)" استفاده می‌شود و براساس استاندارد CPP برخورد با اکسپشن‌ها را فعال می‌کند. به طور پیش فرض، MSVC از فلگ EHs استفاده می‌کند که برخورد با اکسپشن‌های CPP را فعال می‌کند اما از مشخص‌کردن نوع اکسپشن پشتیبانی نمی‌کند. هنگام استفاده از فلگ EHsc، رفتار EHs را توسعه می‌دهد تا شامل پشتیبانی از مشخص‌کردن نوع اکسپشن هم باشد. برخورد با اکسپشن یک مکانیزم در CPP است که به شما اجازه می‌دهد اکسپشن‌ها را در طول اجرای برنامه کنترل و انتقال دهید. این مکانیزم روش ساختاری برای مقابله با شرایط استثنایی یا خطاهایی که در زمان اجرا ممکن است رخ دهند، فراهم می‌کند. این فلگ به هر صورت شرایطی را فراهم می‌کند که کامپایلر به صورت خودکار بتواند شرایط خاص را با استفاده از بلاک‌های دستوری try-catch مبتنی بر استاندارد CPP مدیریت و کنترل کند. با این حال، فعال‌سازی این فلگ موجب می‌شود که مقداری بر روی کد Overhead آورده شود و Performance برنامه به خاطر کنترل‌های اضافی که کامپایلر به باینری اضافه می‌کند، کاهش پیدا کند. فلگ‌های فعال در مُد Release: فلگ GL: این فلگ برای فعال کردن Global Optimization استفاده می‌شود. این بهینه‌سازی به کامپایلر امکان می‌دهد تا عملکرد و سرعت اجرای برنامه را بهبود بخشیده و حجم کد تولید شده را کاهش دهد. با استفاده از پرچم GL، کامپایلر MSVC بهینه‌سازی‌هایی را اعمال می‌کند که بهبود عملکرد برنامه را در مقیاس سراسر برنامه فراهم می‌کند. این بهینه‌سازی‌ها می‌توانند شامل تغییرات در ساختار داده‌ها، بهینه‌سازی‌های ریاضی و منطقی، حذف Dead Code و ترتیب اجرای کدها باشند. با فعال کردن فلگ GL، می‌توانید عملکرد برنامه خود را بهبود بخشیده و زمان اجرا را کاهش دهید. همچنین، حجم کد تولید شده نیز کاهش می‌یابد که می‌تواند منجر به افزایش سرعت بارگذاری و اجرای برنامه شود. به طور معمول، برای استفاده کامل از این بهینه‌سازی، باید فلگ LTCG را در مرحله لینک فعال کنید. این بهینه‌سازی‌ها ممکن است باعث افزایش زمان کامپایل شود، اما عملکرد و سرعت اجرای برنامه را بهبود می‌بخشند. فلگ Gy: فلگ Gy برای فعال کردن Function Level Linking استفاده می‌شود. زمانی که در هنگام کامپایل از فلگ Gy استفاده می‌شود، کامپایلر را به تولید فایل‌های آبجکت جداگانه برای هر تابع در کد مجبور می‌کند. این امر به پیوند کارآمدتر و کاهش حجم فایل اجرایی منجر می‌شود. با فعال کردن Function Level Linking با فلگ Gy، لینکر قادر است توابع بی‌استفاده را از فایل اجرایی نهایی حذف کند و حجم کل باینری را کاهش دهد. این قابلیت به خصوص در پروژه‌های بزرگ که نه همه توابع استفاده می‌شوند و نه همه توابع فراخوانی می‌شوند، مفید است. فلگ Gm-: این فلگ به کامپایلر می گوید که تکنیم Incremental Compilation و همچنین استفاده از فایل های PCH را غیرفعال کند. این دو مورد موجب کامپایل برنامه با سرعت بالاتری می شوند اما در برخی شرایط غیرفعال کردن Incremental Compilation و ایجاد فایل .pch می‌تواند مفید باشد. این مورد مفید است زمانی که در پروژه‌های بزرگ کار می‌کنید و هزینه نگهداری و به‌روزرسانی فایل .pch بیشتر از فواید Incremental Compilation سریع است. در حالت کلی، فلگ‌هایی که در بالا آورده شده‌اند به صورت پیش‌فرض در مُدهای Debug و Release در Visual Studio تعریف شده‌اند. برنامه C که با رویکرد Structها نوشته شده است، در هر دو مُد مورد بررسی قرار گرفته است تا درک بهتری از ساختار باینری همچنین با فلگ‌های گوناگون کامپایلر به دست آورده شود. بررسی دیزاسمبلی x86 در ویندوز به منظور درک دیزاسمبلی ساختمان داده Struct در زبان برنامه نویسی C ابتدا خروجی تولید شده برای معماری x86 را در دو مُد Debug و Release مورد بررسی قرار خواهیم داد. بعد از بررسی خروجی دیزاسمبلی برای معماری x86، خروجی کامپایلر MSVC برای معماری x64 را مورد بررسی و ارزیابی قرار خواهیم داد. تصویر 3: کد منبع برنامه مورد بررسی همانطور که در جدول 1 آورده شده است، خروجی دیزاسمبلی کد منبع در تصویر 3 با فلگ‌های پیش‌فرض کامپایلر برای مُد Debug مورد بررسی قرار گرفته است. اولین نکته‌ای در تحلیل کد منبع نظر من را جلب کرد، نادیده گرفتن inline بودن تابع MyOperation بود. با اینکه این تابع را به صورت inline تعریف کرده بودم، و همچنین فلگ Zc:inline هم فعال بود، با این حال کامپایلر تصمیم گرفته است که این تابع را به صورت inline در محل فراخوانی خود گسترش ندهد. از همین روی در تابع main، یک دستور call داریم. وقتی این دستور فراخوانی می‌شود، آدرس 00C11A66 را در پشته قرار می‌دهد تا وقتی دستور ret فراخوانی شد، جریان اجرای باینری به مسیر صحیح خود بازگردد و ادامه اجرای برنامه را بعد از فراخوانی تابع ادامه بدهد. در تصویر 4، خروجی دیزاسمبلی اجرای این دستور در محیط Visual Studio نمایش داده شده است. وقتی دستور Call اجرا شده است، آدرس دستوربعد بر روی بالا پشته قرار گرفته است که با ارجاع به مقدار ESP-4 در پانل Memory می‌توان مقداری که در بالای پشته قرار گرفته است، مشاهده کرد که این مقدار با رنگ آبی نمایش داده شده است. تصویر 4: خروجی اجرای دستور Call در دیباگر Visual Studio در ادامه همین مسئله در دیزاسمبلر IDA Pro مورد بررسی قرار گرفته است. وقتی باینری مذکور را در دیزاسمبلر IDA Pro باز کنیم، و وارد دیباگر این دیزاسمبلر شویم، موقعی که دستور Call فراخوانی شود، آدرس دستور بعدی را بر روی پشته قرار می‌دهد که دستور Ret بتواند فرایند اجرای باینری را به مسیر صحیح خود بازگرداند. در پانل Stack View این باینری مقداری که درون پشته قرار گرفته است، قابل نمایش است. تصویر 5: خروجی اجرای دستور Call در دیباگر IDA Pro در تصویر 5، دیزاسمبلی باینری را در مُد Release درون دیباگر IDA Pro مشاهده می‌کنیم. همانطور که در تصویر 5 قابل مشاهده است، وقتی دستور Call اجرا شده است، آدرس بعدی خود را درون پشته قرار داده است که بعد از اجرای دستورالعمل ret اجرای باینری بتواند به مسیر اجرایی خود بازگردد. بعد از اینکه وارد تابع MyOpertion شویم، خروجی دیزاسمبلی تعریف و مقداردهی Struct در زبان C قابل مشاهده است. در تصویر 6، دیزاسمبلی تابع MyOperation نمایش داده شده است: تصویر 6: خروجی دیزاسمبلی تابع MyOperation سه دستور اول اصطلاحا Prologue تابع MyOperation هستند. این سه دستور موجب ایجاد یک فریم جدید و ایجاد فضا برای ذخیره‌سازی متغیرهای محلی تابع می‌شوند. دستور push ebp موجب ذخیره سازی فریم تابع قبلی بر روی پشته خواهد شد. دستور mov ebp, esp موجب شکل گیری یک فریم جدید برای تابع MyOperation خواهد شد. دستور sub esp, 66Ch موجب کم کردن مقدار 66C از پشته به منظور ذخیره سازی متغیرهای محلی درون تابع خواهد شد. به هر صورت، این دستورالعمل فضایی برای متغیرهای محلی و داده‌های دیگری که توسط تابع نیاز است، در پشته اختصاص می‌دهد. در ادامه سه دستور PUSH داریم که به نظر می آید به این دلیل انجام می‌شوند که قبل از استفاده از رجیسترهای ebx، esi و edi مقادیر قبلی آن‌ها بر روی پشته ذخیره شود تا در ادامه مقادیر آن‌ها قابل بازیابی بانشد. دستور بعدی آدرس مؤثر [ebp-42Ch] را محاسبه کرده و در رجیستر EDI ذخیره می‌کند. دستور بعدی مقدار 10Bh (هگزادسیمال) را به رجیستر ECX منتقل می‌کند. مقدار درون رجیستر ECX به عنوان میزان تکرار برای دستور rep stos است که در گام بعد آورده شده است. دستور rep stos مقداری که درون EAX قرار دارد، به آدرسی که توسط EDI اشاره می کند، کپی خواهد کرد.
  6. کامبیز اسدزاده

    همه چیز در مورد مجوز و شرایط استفاده از کتابخانهٔ Qt

    یکی از مهمترین و پر‌مخاطب‌ترین سوألاتی که در مورد فریم‌ورک کیوت پرسیده می‌شود، شرایط استفاده و مجوز‌های مربوط به آن است؛ از آنجایی که این کتابخانه تحت پشتیبانی یک شرکت تجاری است، برخی از شرایط و قوائدی وضع شده است که در استفاده از آن باید دقت لازم را داشت. در این مقاله من قصد دارم به توضیحات و شفاف‌سازی کامل در این خصوص بپردازم که امیدوارم از آن بهره‌مند شده و به اشتراک بگذارید. بررسی مجوز‌های جامع Qt ابزار Qt، یک چهارچوب قدرتمند برنامه‌نویسی چندسکویی است که انواع مختلفی از مجوزها را ارائه می‌دهد تا به نیازهای متنوع کاربران خود پاسخ دهد. با توجه به تاریخچهٔ غنی‌ای که به آغاز توسعهٔ آن باز می‌گردد، Qt به تدریج به یکی از اصلی‌ترین بازیگران در زمینه توسعه نرم‌افزار تبدیل شده است که در این مقاله به آن اشاره می‌کنیم. Qt تحت چندین گزینه مجوز مختلف قرار دارد که برای توسعه نرم‌افزارهای مختلف مناسب هستند که به صورت زیر تعریف شده‌اند. مجوز تجاری Qt فریم‌ورک کیوت، زیر مجوزهای تجاری مناسبی را برای توسعه نرم‌افزارهای تجاری فراهم کرده است که کاربران نمی‌خواهند کد منبع خود را با دیگران به اشتراک بگذارند یا نمی‌توانند با شرایط نسخه 3 مجوز GNU LGPL (GNU Lesser General Public License) سازگاری یابند. مجوز LGPL Qt این مجوز برای توسعه نرم‌افزارهای Qt مناسب است، تا زمانی که شما می‌توانید با شرایط نسخه 3 مجوز GNU LGPL (یا GNU GPL نسخه 3) سازگار باشید. مجوز بازار Qt (Qt Marketplace) اجزای Qt تحت توافق‌نامه مجوز بازار Qt مناسب برای توسعه نرم‌افزارهای Qt هستند، معمولاً با شرایط مجوز تجاری یا GNU LGPL (یا GNU GPL نسخه 3) برنامه‌ریزی می‌شوند. استفاده از کد، از طریق مجوزهای متن‌باز فریم‌ورک Qt شامل کدهای شخص ثالثی است که تحت مجوزهای خاص متن‌باز از نویسندگان اصلی مجوزدهی شده‌اند. برخی از سوأل و پرسش‌های جامعه و تیم کیوت در رابطه با مجوز‌ها و اهداف آن‌ها در توسعه چرا Qt همچنین زیر مجوز نرم‌افزار متن باز نیز منتشر می‌شود؟ ما به جنبش نرم‌افزار آزاد اعتقاد داریم که استفاده از نرم‌افزار با حقوق وظایف خاصی همراه است. استفاده از مجوزهای نرم‌افزار متن باز، به کاربران چهار درجه اصلی از آزادی را در استفاده از برنامه‌ها یا دستگاه‌های Qt می‌دهد: آزادی اجرای برنامه برای هر هدفی. آزادی مطالعه نحوه عمل برنامه و سازگارسازی آن با نیازهای خاص. آزادی توزیع نسخه‌های کپی شده تا بتوانید به همسایه خود کمک کنید. آزادی بهبود برنامه و انتشار بهبود‌های خود به عموم، تا کل جامعه بهره‌مند شود. این آزادی‌ها غیرقابل مذاکره و مطلق هستند، نمی‌توان آنها را به صورت انتخابی یا جزئی تجربه کرد، شما همچنین موظف به انتقال آنها به کاربران خود هستید. چرا شما توافقی با KDE در مورد مجوزهای خود دارید؟ KDE چیست و تاریخچهٔ Qt و KDE چگونه است؟ توافق بین Qt و KDE دربارهٔ مجوزها، ریشه در تاریخچهٔ مشترک این دو نهاد دارد. KDE (kde.org) مخفف محیط کاری دسکتاپ (Desktop Environment) است که یک جامعهٔ بین‌المللی نرم‌افزار آزاد است و در سال ۱۹۹۶ تأسیس شد. KDE به خاطر محیط کاری Plasma Desktop شناخته می‌شود که به عنوان محیط کاری پیش‌فرض در بسیاری از توزیع‌های لینوکس به کار می‌رود. نرم‌افزارهای KDE بر پایهٔ چارچوب Qt ساخته می‌شوند. در اوایل توسعهٔ Qt، این چارچوب از یک مدل مجوز دوگانه برخوردار بود و کد منبع آن تحت مجوزهای متن باز اختصاصی قابل دسترس بود. با درک اهمیت Qt برای پروژه‌های خود، KDE تلاش کرد تا توافقاتی برای اطمینان از دسترسی به Qt تحت مجوزهای مناسب متن باز، حتی اگر Trolltech (شرکت بنیان‌گذار Qt) به تصرف بشود یا ورشکست شود، به دست آورد. نتیجهٔ این تفاهم، بنیاد آزاد KDE Qt (KDE Free Qt Foundation) تأسیس شد و توافق‌نامه بنیاد آزاد KDE Qt ایجاد شد. بنیاد آزاد KDE Qt یک سازمان با هدف ایمن کردن دسترسی به چارچوب Qt برای توسعهٔ نرم‌افزارهای آزاد و به‌ویژه برای توسعهٔ نرم‌افزارهای KDE است. این بنیاد در ابتدا توسط Trolltech و سازمان غیرانتفاعی حقوقی KDE (KDE e.V.) در سال ۱۹۹۸ تأسیس شد و یک توافق‌نامهٔ مجوز دارد که تأمین می‌کند که Qt برای پلتفرم‌های اصلی دسکتاپ و موبایل تحت مجوزهای LGPLv3 و GPLv3 در دسترس است. این توافق‌نامه در طی سال‌ها چندین بار به‌روزرسانی شده است، عمدتاً به دلیل انجام معاملات مرتبط با Qt یا به‌روزرسانی مجوزها و پلتفرم‌ها. عدم رعایت محدودیت‌های مجوزهای LGPL/GPL چه تبعاتی دارد؟ اگر نرم‌افزاری که از این کتابخانه‌های مجوز متن‌باز استفاده می‌کند، به طور کامل الزامات مجوز را رعایت نکند، شما حق استفادهٔ مجوز و حقوق توزیع مرتبط با آن را از دست خواهید داد. همچنین لازم به ذکر است که در بیشتر کشورها، نقض حقوق نسخهٔ پدیدآورندگان یک نقض تشریعی است، نه نقض قرارداد، و بنابراین تدابیر تشریعی مرتبط با این موضوع اعمال می‌شود. برای کسب اطلاعات بیشتر در مورد GPL، می‌توانید به صفحه FAQ GPL از لینک آن مراجعه کنید. آیا می‌توانم از نسخهٔ متن باز جوامع برای توسعه محصول تجاری خود استفاده کنم؟ این بستگی به نحوهٔ ارائه و ارائهٔ محصول شما دارد. نسخهٔ متن باز Qt اصلی به طور عمده تحت مجوز LGPL نسخه 3 و GPLv2/v3 منتشر می‌شود. شما باید الزامات مجوزهای این گونه را که در زمان استفاده از Qt در محصول خود باید رعایت کنید. تفاوت بین LGPLv2 و LGPLv3 چیست؟ LGPLv3 نسخه فعلی مجوز GNU Lesser General Public License است. LGPLv2.1 یک نسخه قدیمی‌تر است و برای پروژه‌های جدید توصیه نمی‌شود. هر دو مجوز همان هدف را دارند، یعنی حفاظت از آزادی کاربران برای استفاده و اصلاح نرم‌افزار تحت مجوز LGPL. LGPLv3 این هدف را به وضوح بیان می‌کند. شما باید چیز‌هایی را برای کاربر نهایی فراهم کنید تا نسخه اصلاح شدهٔ کتابخانه تحت مجوز LGPLv3 را نصب کرده و نرم‌افزار خود را با استفاده از آن کتابخانه اصلاح شده اجرا کند. در عمل، این به عنوان مثال به موارد زیر اشاره دارد: Tivoization – به وضوح اجازه ندهید دستگاه‌های بسته سازی‌شده ایجاد شود که کاربر نهایی حقوق مجوز LGPL برای کتابخانه‌های متن باز Qt را ندارد. DRM و رمزگذاری سخت‌افزاری – نمی‌توان از این تعهدات برای دور زدن این تعهدات استفاده کرد. انتقام از پتنت نرم‌افزار – جایی که تمام کاربران نرم‌افزار مجوزها را دارند، که این باعث بی‌معنی شدن انتقام از پتنت نرم‌افزارهایی که ممکن است در نرم‌افزار منتشر شده، می‌شود. وظایف من چیستند هنگام استفاده از Qt تحت مجوز LGPL؟ در ابتدا، باید توجه داشته باشید که تمامی ماژول‌های متن باز Qt تحت مجوز LGPLv3 در دسترس نیستند. برخی از ماژول‌ها برای استفاده در نرم‌افزارهای متن باز تحت GPLv3 قرار دارند و برخی از اجزاء توسعه‌یافته توسط شخص ثالث مانند موتور وب Chromium تحت مجوز LGPLv2.1 در دسترس قرار گرفته‌اند. زمانی که از ماژول‌ها و کتابخانه‌های Qt تحت مجوز LGPLv3 استفاده می‌کنید، برخی از وظایفی که باید رعایت کنید به شرح زیر است: هنگام استفاده از نرم‌افزار متن باز، باید از مجوز هر نمونه، قطعه کد منبع، ماژول و کتابخانه‌ای که در پروژه خود استفاده می‌کنید، آگاه باشید و مجوزهای مرتبط را ردیابی کنید. باید کد منبع کامل کتابخانه‌های Qt که استفاده کرده‌اید را به همراه تمام اصلاحات اعمال شده یا اعمال شده، به کاربران یا مشتریان خود ارائه دهید. به عنوان یک گزینه دیگر، می‌توانید پیشنهاد نامه‌ای با دستورالعمل‌هایی در مورد چگونگی دریافت کد منبع ارائه دهید. لطفاً توجه داشته باشید که این باید تحت کنترل شما باشد، بنابراین ارائه یک لینک به کد منبع ارائه‌شده توسط پروژه Qt یا شرکت Qt کافی نیست. مجوز LGPL به شما این امکان را می‌دهد که کد منبع خود نرم‌افزار را به عنوان «کاری که از کتابخانه استفاده می‌کند» خصوصی نگه‌دارید. به طور معمول، در اینجا پیشنهاد می‌شود که از اتصال پویا استفاده کنید (برای کامپایل استاتیک این مورد مجاز نیست و نیاز به تهیهٔ مجوز دارد). کاربر نهایی باید قادر باشد نرم‌افزار شما را با یک نسخه مختلف یا اصلاح‌شده از کتابخانه Qt مجدداً لینک کند. با LGPLv3، به وضوح ذکر شده است که کاربر باید قادر باشد باینری مجدداً لینک‌شده را بر روی دستگاه هدف خود اجرا کند. این وظیفه به شما محول است که کاربر را با همه ابزارهای لازم برای فعال کردن این فرآیند تجهیز کنید. برای دستگاه‌های جاسازی‌شده، این شامل فراهم‌کردن تمام ابزارهایی است که برای کامپایل کتابخانه استفاده‌شده به کاربران مورد نیاز است. برای اجزاء مجوزده LGPLv3، شما موظف به ارائه دستورالعمل‌های کامل در مورد نصب کتابخانه اصلاح‌شده بر روی دستگاه هدف هستید (این با LGPLv2.1 به طور واضح بیان نشده است، اگرچه اجرای برنامه در برابر نسخهٔ اصلاح شدهٔ کتابخانه با هدف اعلام شده در مجوز است). کاربری که از یک برنامه یا دستگاه که از نرم‌افزار متن باز تحت مجوز LGPL استفاده می‌کند، باید از حقوق خود مطلع شود، با ارائه یک نسخه از مجوز LGPL به کاربر نهایی و نمایش اعلان مشهور در مورد استفاده‌ شما از نرم‌افزار متن باز باید اعلام شود. این آزادی‌ها به هیچ وجه توسط شرایط دیگر مجوز گزینشی نمی‌توانند محدود شوند؛ اگر یک برنامه به کلی از تمام وظایفی که در بالا ذکر شده است پیروی نکند، اجازه توزیع آن به هیچ وجه داده نمی‌شود. همچنین باید اطمینان حاصل کنید که از هیچ ماژولی که تحت مجوز GPL استفاده نمی‌کنید. آیا نیاز است که از مجوز LGPL هنگام استفاده از نسخهٔ تجاری Qt نگران باشم؟ به طور معمول، خیر. هنگام استفاده از نسخهٔ تجاری مجوزگذاری شده Qt، ما تقریباً تمامی بخش‌ها را تحت شرایط یک مجوز تجاری ارائه می‌دهیم. هرچند، چندین ماژول در Qt از کد منبع پروژه‌های متن باز شخص ثالث مانند Qt WebEngine استفاده می‌کنند که از پروژه Chromium با مجوز LGPLv2.1 استفاده می‌کند. بنابراین، هنگام استفاده از این ماژول‌ها، شما باید از تعهدات مجوز مرتبط رعایت کنید، در مورد Chromium این موضوع به مجوز LGPLv2.1 اشاره دارد. تمامی ماژول‌ها و وابستگی‌های شخص ثالثی که توسط ماژول‌های مختلف Qt استفاده می‌شوند، در مستندات Qt برای هر نسخه از Qt مستند شده‌اند. به عنوان یک کاربر مجوز تجاری، در عمل، تنها نیاز دارید که به تعهدات مجوز LGPLv2.1 اهمیت بدهید، و تنها اگر از Qt WebEngine استفاده کنید. چه کاری باید انجام دهم؟ مطمئن نیستم که مطابق مجوزهای متن باز هستم؟ از مجوزهای متن باز گیج شده‌ام، چه باید انجام دهم؟ همیشه خوشحال هستیم که با شما درباره وضعیتتان صحبت کنیم، اما ما در جایی نیستیم که مشاوره حقوقی ارائه دهیم. همیشه توصیه می‌شود با یک وکیل که با مجوزهای متن باز آشنا است، تماس بگیرید تا یک بررسی کامل از پروژه شما صورت گیرد و تصمیم گیری شود که آیا شما می‌توانید تمامی تعهدات مجوزهای متن باز مربوطه (مانند LGPLv/GPLv) را انجام دهید یا خیر. مجوز تجاری Qt چگونه کار می کند؟ آیا همه توسعه دهندگان من باید مجوز معتبر Qt داشته باشند؟ در رابطه با مجوز‌های تجاری، هر کاربر Qt باید مجوز تجاری Qt مختص خود را داشته باشد. طراحان رابط کاربری، هنرمندان فنی، توسعه‌دهندگان نرم‌افزار یا مهندسان اتوماسیون تست ممکن است انواع مختلفی از مجوزهای Qt داشته باشند، اما هر فرد باید یک مجوز اشتراک معتبر داشته باشد. آیا می‌توانم کد نوشته‌شده با Qt متن باز را با Qt تجاری مجوزگذاری شده ترکیب کنم؟ خیر. اگر می‌خواهید از Qt متن باز به یک مجوز تجاری مهاجرت کنید، لطفاً با فروشگاه Qt تماس بگیرید. برای این سوال، موارد بیشتری نیز در لینک FAQ مجوزگذاری تجاری Qt وجود دارد. آیا امکان توزیع برنامه‌های توسعه یافته با نسخهٔ متن باز Qt از طریق فروشگاه‌های عمومی وجود دارد؟ هر فروشگاه اپلیکیشن شرایط و مقررات منحصر به فردی دارد که ممکن است با توزیع برنامه‌ها تحت مجوزهای LGPL یا GPL سازگار یا سازگار نباشد. مجوز تجاری Qt با شرایط و مقررات تمامی فروشگاه‌های اپلیکیشن معتبر سازگار است و بنابراین معمولاً بهترین گزینه برای توزیع یک برنامه به صورت منبع بسته در فروشگاه‌های مختلف است. من شروع به توسعه یک محصول با استفاده از نسخهٔ متن باز Qt کرده‌ام، حالا می‌توانم یک نسخهٔ تجاری از Qt خریداری کرده و کدم را تحت آن مجوز قرار دهم؟ بله. پروژه‌های توزیع‌شده تحت نسخهٔ تجاری Qt نیز باید تحت نسخهٔ تجاری Qt توسعه یابند. اگر قبلاً توسعه را با نسخهٔ متن باز Qt شروع کرده‌اید، ما به همکاری برای یافتن یک راه‌حل برای انتقال پایه کد شما از حاکمیت متن باز به مجوز تجاری می‌پردازیم. اگر از ابتدا مطمئن نیستید که از کدام مجوز یا نسخه برای شروع توسعه استفاده کنید، توصیه می‌شود با The Qt Company تماس بگیرید تا بر اساس نیازهای توسعه‌ی خود شما راهنمایی شود. ممکن است در یک برنامه از کتابخانه‌های دارای مجوز LGPLv2.1 و LGPLv3 استفاده کرد؟ بله، امکان استفاده از هر دو نسخهٔ مجوز LGPLv2.1 و LGPLv3 در یک برنامه وجود دارد، به عنوان مثال با استفاده از آن‌ها به عنوان کتابخانه‌های جداگانه به عنوان shared libraries. انجام این کار نیاز به تغییر مجوز در هیچ یک از کتابخانه‌ها ندارد و در صورت نیاز، امکان انتخاب یک مجوز مولد برای برنامه وجود دارد. ماتریس سازگاری GNU نشان می‌دهد که من نمی‌توانم LGPLv2 و LGPLv3 را ترکیب کنم؟ اگر کد LGPLv2.1 و کد LGPLv3 در کتابخانه‌های جداگانه به عنوان shared libraries قرار داده شوند، می‌توانند در یک برنامه استفاده شوند، و شما می‌توانید برنامه خود را با یک مجوز مالکیتی / LGPLv2.1 / LGPLv3 به دلخواه خود مجوزگذاری کنید. در مورد نسخهٔ مجوز LGPL/GPL که شما استفاده می‌کنید، چه کسانی مهم هستند؟ شما، مشتریان شما و کاربران نهایی، مگر اینکه از Qt تحت یک مجوز تجاری استفاده کنید. مجوزهای copyleft مانند LGPL و GPL به این معناست که مجوز با محصول شما به مشتریان و کاربران یا راه‌حل شما همراه می‌شود. با توجه به تمامی توضیحات موجود، به طور خلاصه چه زمانی نیاز به تهیهٔ مجوز‌های کیوت داریم؟ تهیهٔ مجوز کتابخانه Qt بستگی به نوع کاربرد و نیازهای پروژه دارد. جوانب مختلفی که تعیین می‌کنند چه زمانی نیاز به مجوز Qt داریم و چه مواردی ممکن است بدون نیاز به مجوز باشند. استفادهٔ شخصی: نیاز به مجوز: اگر برنامه‌نویس قصد استفاده از Qt را برای توسعهٔ پروژهٔ شخصی و خصوصی دارد بدون انتشار کد منبع، نیاز به مجوز ندارد. در این حالت، می‌توان از Qt به صورت رایگان استفاده کرد. بدون نیاز به مجوز: استفاده از Qt برای پروژه‌های شخصی بدون هدف انتشار کد منبع با محدودیتی همراه نخواهد بود. توسعهٔ نرم‌افزار باز (Open Source): نیاز به مجوز: اگر قصد توسعهٔ یک نرم‌افزار منبع باز با Qt را دارید و می‌خواهید کد منبع خود را نیز تحت یک مجوز Open Source انتشار دهید، نیاز به مجوز GPL یا LGPL خواهید داشت. بدون نیاز به مجوز: اگر نیازی به انتشار کد منبع ندارید و از Qt برای پروژه منبع باز خود استفاده می‌کنید، می‌توانید از نسخهٔ Qt با مجوز LGPL بدون مشکل استفاده کنید. توسعهٔ نرم‌افزار تجاری (Commercial Software): نیاز به مجوز: اگر قصد توسعهٔ نرم‌افزار تجاری دارید و نمی‌خواهید کد منبع خود را انتشار دهید، نیاز به مجوز تجاری Qt دارید. بدون نیاز به مجوز: اگر از Qt برای توسعهٔ یک نرم‌افزار تجاری استفاده می‌کنید و توافق به اشتراک‌گذاری کد منبع ندارید، می‌توانید از نسخهٔ تجاری Qt بهره‌مند شوید. توسعهٔ نرم‌افزار تحت LGPL: نیاز به مجوز: اگر می‌خواهید نرم‌افزار تجاری توسعه دهید، اما نیاز به استفاده از کتابخانه Qt دارید و می‌خواهید تغییرات خود را در کتابخانه منتشر کنید، باید از مجوز LGPL استفاده کنید. بدون نیاز به مجوز: اگر قصد استفاده از Qt را در یک نرم‌افزار تجاری با حفظ محرمانگی کد دارید، می‌توانید از مجوز تجاری Qt بهره‌مند شوید. برخی از نکات را نیز باید در نظر بگیرید، مانند نوع کامپایل و نوع مجوز‌های قابل پذیرش در فروشگاه‌ها که عموماً همهٔ آن‌ها را توضیح دادیم به چه صورت هستند.
  7. کامبیز اسدزاده

    جزئیات، به‌روز رسانی‌ها و ویژگی‌های C++23 همانطور که می دانیم، مدیریت خطا در سی‌پلاس‌پلاس به وسیلهٔ بیانیه‌های try، catch و throw انجام می‌شود. این ویژگی به برنامه‌نویس این امکان را می‌دهد که خطاها را شناسایی کرده و به دسته‌بندی کرده و سپس به شکل مناسبی برخورد کند. همچنین کلاس‌هایی مانند std::exception یک کلاس پایه در سی‌پلاس‌پلاس است که برای نمایش استثناء‌ها (خطاها) در هنگام اجرای برنامه استفاده می‌شود. این کلاس یک رابط عمومی به نام what دارد که متنی که توضیح خطا را حاوی می‌شود، به عنوان یک رشته C-style (const char*) باز می‌گرداند. مدیریت خطای جدید std::expected معرفی شده در استاندارد ۲۳ در استاندارد جدید ۲۳ گزینهٔ std::expected معرفی شده‌است که اجازه می‌دهد خطاها را بهتر مدیریت کنیم. این نوع داده به شما این امکان را می‌دهد که یک عدد بازگشتی معمولی (نتیجه موفقیت‌آمیز) یا یک کد خطا (نتیجه ناموفق) را با هم در یک متغیر ذخیره کنید. برای برنامه نویسانی که از این نوع داده استفاده می‌کنند، کد برنامه خواناتر و قابل‌فهم‌تر است. استفاده از std::expected معمولاً در جاهایی مناسب است که خطاها قابل پیش‌بینی و مدیریت شوند. در زیر یک نمونه کد در قالب مثال بر پایهٔ سی‌پلاس‌پلاس جدید آورده شده است: import <print>; import <expected>; enum class ErrorType { InvalidName, NotFound, OtherError }; auto getName(std::string name) -> std::expected<std::string, ErrorType> { if (name != "Kambiz") { return std::unexpected(ErrorType::InvalidName); } return name; } auto main() -> int { auto result = getName("Compez"); if (result.has_value()) { std::println("Result: {}", result.value()); } else { ErrorType error = result.error(); switch (error) { case ErrorType::InvalidName: std::println("Error: Invalid Name!"); break; case ErrorType::NotFound: std::println("Error: Not Found!"); break; case ErrorType::OtherError: std::println("Error: Other Error!"); break; } } return 0; } در اینجا، یک تابع به نام getName تعریف شده است که یک نام به عنوان ورودی دریافت می‌کند و یک std::expected را باز می‌گرداند. اگر نام "Kambiz" نباشد، یک std::unexpected با ErrorType::InvalidName ایجاد می‌شود و اگر نام معتبر باشد، خود نام به عنوان مقدار بازگشتی استفاده می‌شود. سپس در تابع main، ما از تابع getName برای دریافت نتیجه استفاده می‌کنیم. اگر نتیجه دارای مقدار باشد (با فراخوانیhas_value())، آن مقدار با استفاده از value() چاپ می‌شود. اگر نتیجه دارای خطا باشد، ما با استفاده از error() نوع خطا را دریافت کرده و با استفاده از یک switch به تصمیمات مرتبط با نوع خطا می‌رسیم و پیام مناسب چاپ می‌شود. توجه داشته باشید که در دسترسی بهerror()، ممکن است بعضی از پیاده‌سازی‌های expected به جای error() از value() برای دسترسی به خطا استفاده کنند. به نظر می‌رسد این ویژگی می‌تواند به صورت چشم‌گیری روش مدیریت خطاها را بهبود سازد. ماژول‌ها و وارد کردن کتابخانه‌های استاندارد به پروژه به صورت ساده و بهینه توسطimport std; و import std.compat; در استاندارد ۲۳ قبلاً من توی پروژهٔ سل و حتی قالب PT یه بخشی برای بهبود و بهینه‌سازی فایل‌های کتابخانهٔ استاندارد (هدر فایل‌ها) به عنوان pch گذاشته بودم. این کار باعث می‌شد که پروژه در سرتاسرش هر جا اس کتابخانهٔ STL استفاده می‌شد رو نیازی به وارد کردن فایل‌ها نباشه. این کار موجب بهینگی کامپایل می‌شه. حالا توی استاندارد ۲۳ چیزی مشابه این موضوع رو به صورت استاندارد شده تعبیه کردن که از شلوغی و اضافات لازم به شدت جلو گیری می‌کنه و سرعت کامپایل هم افزایش پیدا می‌کنه. ️ بهتر بخوام توضیح بدم دیگه نیازی نیست کدی مثل زیر داشته باشید: #include <algorithm> #include <array> #include <print> auto main() -> int { std::array<int, 10> s {5, 7, 4, 2, 8, 6, 1, 9, 0, 3}; std::sort(s.begin(), s.end()); for(auto el : s) { std::println("Sorted Index: {}", el); } } کافیه به شیوهٔ زیر بنویسید: import std; auto main() -> int { std::array<int, 10> s {5, 7, 4, 2, 8, 6, 1, 9, 0, 3}; std::sort(s.begin(), s.end()); for(auto el : s) { std::println("Sorted Index: {}", el); } } در واقع استفاده از ;import std تمامی کتابخانه‌های استاندارد رو وارد می‌کنه و استفاده از ;import std.compat مثل همون هست اما با تفاوت این ‌که کتابخانه‌های عمومی C رو هم وارد خواهد کرد. فکرشو بکن ده‌ها و صد‌ها کتابخانه STL رو وارد فایل‌ها می‌کنی! اما الآن کافیه همین یه خط رو بنویسی دنیای ماژول‌ها در سی‌پلاس‌پلاس جدید خیلی تمیزه!
  8. توضیحاتی که در این پست ارائه می‌کنم، به منظور این نیست که بگم چیزی بد هست یا چیزی خوب! یکی بهتر است و دیگری بدتر! اما دوست دارم بیشتر با جو تبلیغاتی غالب روی چیزی نظر ندیم و در برنامه‌نویسی هم شخصاً تمایل دارم به بالاترین سطح ممکن از آزادی عمل در یک ابزار برسم که همه چیز رو برای یک برنامه‌نویس فراهم می‌کنه. مثالی که قبلاً زده بودم همون بحث باغ‌وحش و حیاط وحش بهترین مثال ممکن هست که می‌تونستم بزنم ولی خب اهل تفکر باید باشی تا بفهمی چی گفتم. بذار یه چیز‌هایی در مورد Rust و C و ++C بهتون بگم تا دیگه نیازی برای ادامهٔ بحث‌های پیش پا افتاده نباشه (این بحث‌ها مسخرست و صرفاً وقت شما رو می‌گیره، اما آگاهی داشتن در موردش می‌تونه دیدگاه بهتری برای پیشروی بهتون بده) اما موضوعاتی که بهش اشاره می‌کنم رو اگه کمی عمیق‌تر بهش دقت کنی، خواهی دید که چرا چیزی مثل سی‌پلاس‌پلاس واقعاً بی‌رقیبه. قبل از هر چیز بهتره مروری از به وجود اومدن این زبان‌ها رو داشته باشیم: وقتی در دههٔ ۷۰ میلادی زبان C به وجود اومد، به عنوان یک ابزار به شدت قابل تحسین با ۱۰۰٪ آزادگی عمل معرفی شد، شما هر سیستم و هر ساختاری رو که می‌خواستی می‌تونستی باهاش بسازی! به هر حال کامپیوتر یک جهان جدیدی بود و هر چیزی در اون می‌تونست یک فرصت باشه؛ همین الآن بعد از گذشت ۵۲ سال خیلی‌ها فکر می‌کنن این زبان منسوخ شده! در حالی که طبق آخرین مستندات N3096 استاندارد C23 در ۲ آوریل ۲۰۲۳ به صورت پیش‌نمایش منتشر شده و هنوز هم در حال توسعه و پیشرفته! یادتونه گفتم هیچ ابزار و فناوری‌ای تا زمانی که در حال توسعه باشه، غلطه که بهش بگیم منسوخ شد! تقریباً ۳۹ سال پیش، وقتی سی‌پلاس‌پلاس به وجود اومد کاملاً ویژگی‌های C رو به ارث برد، در واقع هر چیزی که C داره، هم مشکلات و هم مزایا در ++C هم وجود داره اما خیلی فراتر از مباحثی که فکرش رو می‌کردند به یک باره توسعه‌پذیر شد. خیلی خب باید بپذیریم مشکلاتی که C داشته را هم در بعضی جاها ++C خواهد داشت، اما نه به صورت یک مانع! چون برای همشون راهکار وجود داره، هیچ چیز بی دلیل ساخته نمیشه، این رو مطمئن باش به‌روز رسانی‌ها بی دلیل نیستند. در مورد Rust، که ۸ سال پیش وقتی به وجود اومد که حتی به ۱۰ سال هم عمر و پختگیش نمیرسه صرفاً تمرکزش به ادامهٔ مسیر‌های مشابه زبان‌های مدیریت شده بود اما در حوزه‌ها و منظور‌های متنوع‌تر که این موضوع جذابش می‌کنه. راست یک زبان سیستمی هست اما با دارا بودن خاصیت Ownership که به همراه یک سری قوانین مثل Transfer Rules و Borrowing خیال شما رو از بحث ایمنی راحت می‌کنه. همین موضوع مسیر Rust رو با C و ++C جدا می‌کنه و قابل قیاس نیستند که در ادامه می‌گم چرا. موضوع مدیریت خودکار حافظه این بحث برتری حساب نمیشه چون توی سی++ مدرن ما راهکار‌های مشخصی برای مدیریت این مسائل داریم. خب یعنی چی یه ابزار داشته باشیم که بیاد امکان برنامه‌نویسی سیستمی رو بده اما مطمئن؟! قطعاً یه جای کار داره می‌لنگه! عین اینه که بگی من اینترنت دارم ولی فیلترینگ شدیدی روش هست، بله نمی‌ذاره من آزادانه و اونطور که می‌خوام پیش برم، هرجا ریسکی بود به عهدهٔ خودمه هرجا خیری بود باز به نفع خودمه. زور و فشار هیچ‌وقت موجب پیشرفت عمیق نمیشه حتی در فناوری! چون شما اختیار عمل ندارید و محبورید با محدودیت‌هایی که اعمال می‌شه پیش‌روی کنید. ساختار مهمی که راست داره بحث موضوع Ownership یا همون مالکیت هست، این یعنی چی؟ یعنی مالک خودش شیء‌ای هست که مسئولیت مدیریت حافظهٔ اختصاص داده شده به یک شیء رو به عهده می‌گیره. در کنار این موضوع قانون انتقال یا همون Transfer می‌گه که هر شیء‌ای فقط یک مالک داره و مالکیت اون‌ها تنها می‌تونه به یک شیء دیگر منتقل بشه! این یک قانون اصلی و مهم در راست هست که برای تضمین این موضوع قانون امانت یا همون Borrowing می‌گه که اگه می‌خوای از یک شیء به عنوان مالک نهایی استفاده کنی، می‌تونی مالکیت به شکل امانت رو به شی‌ء دیگری انتقال بدی که در حالت قرضی یا موقتی ممکن هست اما اجازه نداری هرطور که دلت خواست ازش استفاده کنی. خب این قانون محدودیت‌های شدیدی رو ایجاد می‌کنه، اما در عوض بله تضمین می‌کنه که مدیریت حافظه مطمئن هست. این باعث می‌شه خطاهای حافظه به خاطر وجود مالکیت اختصاصی، که در زمان کامپایل، کامپایلر تعیین می‌کنه که چه زمانی باید حافظه آزاد بشه رو جلوگیری می‌کنه. شما نمی‌تونید به صورت آزاد روی مدیریت حافظه حرفی برای گفتن داشته باشید چون شما آزادی عمل ندارید. در مقابل در سی‌پلاس‌پلاس بدون هیچ محدودیتی از این موضوع بهره می‌برید. دسترسی به لایه‌های سخت‌افزاری عمیق و پشتیبانی از abi‌های سیستم‌عامل‌ها به صورت کامل تحت راست ممکن نیست مگر اینکه به صورت اختصاصی نسبت به هر abi در اختیار شما خارج از استاندارد‌ها قرار بگیره، چیزی که در سی‌پلاس‌پلاس همه چیز به صورت استاندارد در اختیار توسعه‌دهنده قرار می‌گیره. کتابخانه‌های استاندارد Rust قابلیت کنترل مستقیم روی ترد (نخ)‌ها رو ارائه نمی‌کنه هرچند مدعی هستن که از روش‌های crate در کامپایلر راست در زمان اجرا با استفاده از thread_priority‌ها قابل پیاده‌سازی هست اما با این حال، هیچ‌وقت در سطح فوریتی به اندازهٔ API‌های استاندارد ++C قابل استفاده نیست، حتی C هم در این حد و اندازه امکان مدیریت سخت‌افزار رو برای شما نمیده. در صورتی که در Rust لایهٔ امنیتی رو فعال هست (چیزی که به صورت پیش‌فرض در راست فعال هست) دیگه امکان دسترسی به لایه‌های سخت‌افزاری رو از دست خواهید داد. در حالی که سی++ این امکان رو به صورت کاملاً آزاد در اختیار شما قرار میده و شما با پذیرش خطر اون اگر تسلط خوبی داشته باشید می‌تونید به بهترین شکل ممکن دسترسی نامحدود به این موضوع رو در اختیار بگیرید. شما در راست فقط حق انتخاب بر مبنای قوائد از پیش تعریف شده رو دارید، یا ایمن باش و محدود باش، یا ایمن نباش و باز هم محدود باش! این در سی++ برعکسه! شما یا باید کد ایمن بنویسی و در عین حال به بالاترین کارآیی دسترسی داشته باشی، یا باید به خاطر عدم داشتن تسلط بالا خطر‌هاش رو بپذیری که صد البته برای کاهش مسائل راهکار‌های استاندارد‌های جدید بهترین گزینست. تمام چیزی که راست ادعا کرده کلاً بر مبنای محدودیت‌های اعمال شده هست، برای مثال شما هیچ راه استاندارد و بومی شده‌ای برای دسترسی API‌های سیستمی به شیوهٔ مستقل از سکو رو ندارید مگر مواردی چون windows-rs و مشابهش که کاملاً خارج از بحث استاندارد و به نوع سوم در دسترس توسعه‌دهنده‌ها قرار می‌گیرند و مناسب چند-سکویی واقعی نیست. جامعهٔ پخته و اکو‌سیستم راست هیچ‌وقت به اندازهٔ زبان‌های C و ++C گسترده نیست و کتابخانه‌های استانداردِ بی‌شماری از این بابت در اختیار توسعه‌دهنده‌ها قرار نگرفته و این قابلیت مقایسه با عمق مستنداتی که طی چندین دهه برای زبان‌های دیگه موجود هست رو نداره. راست به معنای واقعی کلمه یک زبان ایمن هست اما با فعال بودن لایهٔ ایمنی، قدرتمند نیست و زیرساخت‌های سنگین که قدرت مانور کامل روی سخت‌افزار رو به شما بده. راست به هیچ عنوان بهینگی لازم رو به خاطر قوائد ایمنی در زمان اجرا (Run-Time) رو نداره در حالی که در ++C شما بهینگی به شدت بالایی رو برای زمان اجرا می‌تونید اعمال کنید. در راست که مدعیه یک زبان سطح‌پایین هست، ما مفهومی به عنوان Placement new نداریم، حتی معنا هم براش نداره چون دیگه محدودیت مالکیت (Onwership) با این موضوع هم خونی نداره و چنین ادعاهایی رو راحت رد می‌کنه. در سطوح پیشرفته، توسعه‌دهنده در ++C با استفاده از Placement new، می‌تونه یک شیء رو در یک مکان خاص از حافظه ایجاد کنه، بدون اینکه حافظه جدیدی بهش اختصاص بده! این امکان به شما اجازه میده که به طور دقیق مشخص کنید کجا باید یک شیء ایجاد بشه! چیزی که حتی در C هم به اندازهٔ ++C در مورد کنترل، سازگاری و انعطاف‌پذیری در مدیریت حافظه رو به ارائه نمی‌کنه. و اما در مورد بحث مسائل زمان اجرا و کامپایل، بله راست به دلیل ویژگی‌هایی که داره در زمان کامپایل مشکلات قابل بروز در زمان اجرا رو کنترل می‌کنه، در مقابل استاندارد‌های جدید از سی‌پلاس‌پلاس نیز ویژگی‌هایی مثل Contracts‌ها و Concepts‌ها رو برای این منظور در نظر گرفته که اگه با استاندارد جدید آشنا نباشید طبیعتاً کد‌های شما در زمان اجرا ممکنه ایمن نباشه. خلاصهٔ کلام اینه که هر زبانی در جای خودش مزایا و معایب خودش رو داره که معمولاً برای تبلیغات و حمایت شدن توسط جامعه، طبیعیه که باید بعضی از مسائل رو نادیده بگیره و بعضی از مزایا رو بیشتر مطرح کنه. در مورد راست هم همینطور، در مورد سی‌پلاس‌پلاس هم همینطور! نا نمی‌تونیم بگیم همه چیز بده یا همه چیز خوبه! قطعاً در مقابل امنیت شک نکنید باید یک سری چیز‌ها رو در نظر بگیرید و در مورد آزادی توسعه توسط یک زبان هم همچنین. به‌روز رسانی‌های اخیر سی‌پلاس‌پلاس طوری پیش رفته که وقتی بخوای به عنوان یک زبان مدرن ازش استفاده کنی، اصولاً دیگه جای بحثی از نظر ترس و وحشت یا مشکلات حافظه یا چنین مسائلی باقی نمی‌مونه. این بر می‌گرده به توسعه‌دهنده که واقعاً از چه نسل و استانداردی تبعیت می‌کنه.
  9. بیت‌کوین در سال ۲۰۰۹ به عنوان یک ارز دیجیتال و یک پلتفرم غیرمتمرکز همتا به همتا راه انداخته شد که کنترل اموال را به همه افراد می‌دهد. ساتوشی ناکاموتو این پلتفرم را معرفی کرد و از آن زمان به کاربری گسترده رسیده و سرمایه‌گذاری با ارزش بازار بیش از ۳۵۳ میلیارد دلاری را به دست آورده است. به عنوان یک گزینه سرمایه‌گذاری، بیت‌کوین دارای ماهیت نوسانی است و برای افرادی که حاضر به پذیرش ریسک هستند، ثروت‌آفرین بوده است. حتی برخی از متخصصان مالی ادعا می‌کنند که قیمت یک بیت‌کوین ممکن است در چند سال آینده به بیش از ۴۰۰ هزار دلار برسد، این که این دارایی بهتر از طلا به عنوان یک ذخیره ارز باشد. فناوری مورد استفاده در بیت کوین نیز در نوع خود بی نظیر است. ناکاموتو استفاده از الگوریتم های ++C را برای طراحی این فناوری مالی انتخاب کرد، اما چرا؟ مدیریت حافظه مدیریت منابع یکی از حیاتی‌ترین مسائلی است که توسعه‌دهندگان در هنگام ایجاد نرم‌افزار در نظر می‌گیرند. برای اینکه یک نرم‌افزار بتواند کلیه ویژگی‌های خود را به دست آورده و همچنان در ارائه خدمات بسیار موثر باقی بماند، باید پروتکل‌های مناسب مدیریت منابع داشته باشد. در توسعه بلاکچین، وضعیت تا حد زیادی تفاوت ندارد. از آنجا که بلاکچین خدماتی را به میلیون‌ها نفر و نهاد ارائه می‌دهد، باید برای کارایی در ارائه خدمات بسیار مقیاس‌پذیر باشد. تحقیقات اخیر از Statista نشان می‌دهد که شبکه بیت‌کوین در سومین سه‌ماه سال ۲۰۲۰ بیش از ۳۵۰ هزار تراکنش روزانه داشت. بعضی از این تراکنش‌ها شامل مقادیر زیادی پول دیجیتال هستند و به عنوان نتیجه نیاز به محاسبات طولانی دارند. ایده اصلی ایجاد بلاکچین توسط ناکاموتو، ایجاد یک شبکه برای تسهیل تعاملات مالی و تسریع در فرآیندها بود. بهترین زبان برنامه‌نویسی برای یک سیستم با این ویژگی‌ها الگوریتم‌های سی‌پلاس‌پلاس است. الگوریتم‌های سی‌پلاس‌پلاس می‌توانند با استفاده بهینه از منابع و کنترل بر روی استفاده از CPU و حافظه، در سطح بهترین عمل کنند. این الگوریتم همچنین به بلاکچین اجازه می‌دهد تا بلوک‌ها را پذیرفته یا رد کند، بنابراین هر گونه تفکیک در بلاکچین را از بین می‌برد. استفاده از C++ بنابراین به پلتفرم کمک می‌کند تا با نرخ سریع با نقاط پایان مختلف تعامل کند. جداسازی کد توسعه نرم‌افزار، شامل بلاکچین، باید فضای کافی برای عملیات تعیین‌پذیر فراهم کند. در مورد بلاکچین، عملکردهای تعیین‌پذیر، هنگامی که به درستی اجرا می‌شوند، تضمین می‌کنند که تراکنش‌ها و فرآیندهای داخلی مانند قراردادهای هوشمند همواره به یک شیوه خدمت می‌کنند حتی زمانی که در دستگاه‌های مختلف قرار دارند. اما تنها راه توسعه‌دهندگان و متخصصان کد نحوه دستیابی کامل به عملیات تعیین‌پذیر را اعمال جداسازی کدها می‌دانند. چه چیزهایی باید توسعه‌دهندگان جدا کنند؟ از آنجا که عملکردهای اجرا شده تعیین‌پذیر هستند، توسعه‌دهندگان باید راهی برای جدا کردن عناصر غیرتعیین‌پذیر از کد قرار دهند. سی‌پلاس‌پلاس از قابلیت‌های فضای نام (namespace) بهره‌مند است که به برنامه‌های دیگر قابل انتقال هستند. این فضاهای نام به جلوگیری از تداخل در عملکرد کدها کمک می‌کنند. همچنین ویژگی کلاس وجود دارد که به جدا کردن و تعیین مرزها بین API کمک می‌کند. قابلیت اطمینان و رسالت ++C یکی از ویژگی‌های حیاتی دیگری که به انتخاب ساتوشی ناکاموتو از سی‌پلاس‌پلاس به عنوان زبان اصلی برنامه‌نویسی بیت‌کوین کمک کرد، ویرایش و به‌روز رسانی‌های اساسی سی‌پلاس‌پلاس است. ++C اغلب به‌روزرسانی می‌شود تا اطمینان حاصل شود که همواره باقی بماند و قابل اطمینان و به‌روز باشد. علاوه بر این، ++C دارای ابزارهای دیباگ و تجزیه و تحلیل مختلف است، تمامی این ابزارها به تقویت عملکرد آن کمک می‌کنند. این ابزارها همچنین امکان شناسایی هر مشکلی را در زمان برنامه‌نویسی فراهم می‌کنند. قابلیت اطمینان و ویرایش سی‌پلاس‌پلاس آن را به پایدارترین زبان برنامه‌نویسی برای توسعه بیت‌کوین تبدیل می‌کند که همچنین اطمینان می‌دهد که نرم‌افزار ساخته شده دارای امنیت بسیار بالاتری باشد. نخ‌ها (Threading) نخ‌ها یا ترد، در برنامه‌نویسی شامل یک مجموعه از دستورالعمل‌ها، فعالیت‌ها یا وظایفی هستند که می‌توانند به طور صاف یا هماهنگ با یکدیگر اجرا شوند. دو نوع عملکرد باید در هر نرم‌افزار یکپارچه باشند، یعنی وظایف موازی و غیرموازی. یک پروژه بلاکچین بیت‌کوین هرگز نمی‌توانست کار کند اگر وظایف موازی و غیرموازی هماهنگ عمل نمی‌کردند. اما یکی از پیچیده‌ترین چیزها در برنامه‌نویسی، ادغام این وظایف است و بیشتر زبان‌های برنامه‌نویسی در حال حاضر معمولاً تمرکز بر روی یکی از این دو وظیفه، یعنی موازی یا غیرموازی دارند. اما سی‌پلاس‌پلاس یکی از قابلیت‌های نخی قابل تحسین دارد که توسعه‌دهنده را قادر می‌سازد همزمان از هر دو وظیفه موازی و غیرموازی استفاده کند. سی‌پلاس‌پلاس می‌تواند به‌طور کارآمد نخ‌های چندگانه را اجرا کرده و امکان ارتباط همگانی و قابل اعتماد بین تمام نخ‌ها را فراهم کند. علاوه بر این، نخ‌های ایجاد شده توسط سی‌پلاس‌پلاس می‌توانند در نقطه بهینه‌ترین عمل کنند، بنابراین کل بلاکچین به طور بهینه عمل می‌کند. با توجه به عملکرد بهینه این زبان، می‌توان گفت یک دلیل دیگر که ساتوشی ناکاموتو از سی‌پلاس‌پلاس استفاده کرد، این است که این زبان امکان نخبندی آسان برای وظایف موازی و غیرموازی را فراهم می‌کند. قابلیت (Move Semantics) قابلیت (Move Semantics) یک عملکرد است که به توسعه‌دهندگان امکان می‌دهد محتوا را بین اشیاء جابجا کنند به جای اینکه فقط محتوا را کپی کنند. با استفاده از قابلیت جابه‌جایی اشیاء و ...، توسعه‌دهندگان و کاربران بر اساس نیاز دسترسی به کپی‌های مختلف اطلاعات دارند، که عملکرد را افزایش داده و تکرار را کاهش می‌دهد. تبعیت از استاندارد‌ها و رعایت قوائد انرژی سبز انرژی سبز یکی از چالش‌های اصلی در صنعت بلاکچین و تولید بیت‌کوین است. به دلیل محاسبات پیچیده و فرآیند استخراج معدنی که برای تولید بیت‌کوین انجام می‌شود، مصرف انرژی این فعالیت‌ها به سرعت افزایش می‌یابد. سی‌پلاس‌پلاس به عنوان زبان اصلی برنامه‌نویسی بیت‌کوین، به طور چشمگیری به بهینه‌سازی مصرف انرژی متمایل است. استانداردهای مصرف بهینه انرژی در طراحی و اجرای برنامه‌ها، این زبان را به یک انتخاب پایدار برای پروژه‌های مرتبط با بلاکچین و ارزهای دیجیتال می‌کند. این به معنای کاهش آثار منفی بر محیط زیست و همچنین صرفه‌جویی در هزینه‌های انرژی مرتبط با فرآیند تولید بیت‌کوین می‌باشد. همچنین، با توجه به گستردگی بیت‌کوین و تاثیر زیاد آن بر مصرف انرژی جهان، تلاش برای استفاده از زبان‌های برنامه‌نویسی با بهینه‌ترین مصرف انرژی، اهمیت فوق‌العاده‌ای پیدا کرده است. سی‌پلاس‌پلاس با امکانات بهینه‌سازی و مدیریت منابع به کاربران این امکان را می‌دهد که به نحوی کارایی انرژی را بهبود بخشند و در طولانی مدت، اثرات محیطی مرتبط با تولید بیت‌کوین را کاهش دهند. از این رو، اهمیت انتخاب این زبان برای توسعه بیت‌کوین نه تنها در جنبه‌های فنی بلکه در جنبه‌های محیطی نیز بیان می‌شود. بهتر است نظر سازندهٔ سی‌پلاس‌پلاس در مورد استفاده از این ابزار برای ارز دیجیتال را هم بدانیم در اشتراک بین خالق زبان برنامه‌نویسی سی‌پلاس‌پلاس، بیارنه استرواستروپ و ساتوشی ناکاموتو، اشاره به زبان برنامه‌نویسی ++C و موضوع ماینینگ بیت‌کوین با تأکید بر مصرف انرژی بالا و تأثیرات آن بر محیط زیست است. چندی پیش در یک پادکست هوش مصنوعی با مجری Lex Fridman، استرواستروپ در مورد نحوهٔ استفاده از سی‌پلاس‌پلاس و عدم کنترل بر نحوه استفاده از ابزارهای توسعه‌دهنده صحبت کرده و به‌ویژه به ماینینگ بیت‌کوین اشاره کرده است. او به عنوان خالق زبان سی‌پلاس‌پلاس ابراز خوشحالی از برخی از کاربردهای این زبان و ناراحتی از برخی دیگر اشاره کرده و به مصرف انرژی بالای ماینینگ بیت‌کوین اشاره کرده است. استرواستروپ از مصرف انرژی فعلی ماینینگ بیت‌کوین به خوشایندی خاصی احساس نمی‌کند و این موضوع را به دلیل انتخاب سی‌پلاس‌پلاس به عنوان زبان برنامه‌نویسی توسعه بیت‌کوین توسط ساتوشی ناکاموتو ذکر کرده است. از نظر استراس‌تروپ سی‌پلاس‌پلاس، یک زبان برنامه‌نویسی قدرتمند و گسترده است که در حوزه‌های مختلف برنامه‌نویسی مورد استفاده قرار می‌گیرد. این زبان امکانات بالایی برای مدیریت حافظه، کارایی بالا، و امکانات چندپارادیمی (مانند برنامه‌نویسی شیءگرا) فراهم می‌کند که در سراسر منابع کد بیت‌کوین شاهد آن هستیم. اما عامل ناراحتی او، مصرف انرژی بالا ممکن است که به علت نحوه استفاده یا پیاده‌سازی خاص از زبان و ابزارهای مرتبط با آن باشد و نه ضعف اساسی زبان سی‌پلاس‌پلاس، چرا که این زبان یکی از نام‌‌دار‌ترین زبان‌های است که مصرف انرژی و منابع را به بهترین حالت ممکن می‌توان در آن مدیریت کرد، از طرفی در صورت پیاده‌سازی نه چندان مطلوب کد‌ها، ممکن است نتیجهٔ عکس بدهد. در واقع معتقد است ممکن است کد‌نویسی بهینه‌ای صورت نگیرد و منجر به مصرف نسبتاً بالایی داشته باشد. وقتی ساتوشی بیت‌کوین را نوشت، او به‌طور ضروری پیش‌بینی نکرد که مسابقه‌ای که به وجود آمد باعث ساخت دستگاه‌های ASIC ماینینگ خواهد شد. در واقع، در صفحهٔ سفید اصلی بیت‌کوین که تنها 9 صفحه است، ساتوشی کلمه CPU را به مجموع 10 بار اشاره کرد. مصرف انرژی کنونی بیت‌کوین کمتر بود اگر ماینینگ به شکلی انجام می‌شد که ساتوشی پیش‌بینی کرده بود. حتی ساتوشی نیز از همان سرنوشتی که استرواستروپ هشدار داد: عدم کنترل بر نحوه استفاده از ابداع خود در آینده، مصون نبود. احتمالاً ساتوشی هم پیش‌بینی نکرده بود که بیت‌کوین در میان مجرمان نیز استفاده خواهد شد. اگرچه ممکن بوده باشد که در یک دوره زمانی بیت‌کوین محبوبیت زیادی در میان تجار مواد مخدر داشته باشد، اما مونرو به عنوان رمزارز انتخابی در میان بسیاری از گروه‌های جرمی ظاهر شده است. فعالیت‌های بشر که در مقیاس بزرگ بر محیط زیست تأثیر منفی می‌گذارند، زیاد است. بنابراین، هیچ توجیه منطقی برای اختصاص به‌طور خاص به ماینینگ بیت‌کوین وجود ندارد، به‌ویژه زمانی که مزیت مثبت آن به حداکثر است. اختصاص مصرف انرژی به ماینینگ رمزارز به‌منظور ایجاد و حفظ یک سیستم همتا به منظور تبادل مالی، یک کار کارآمد است چرا که دقیقاً همان چیزی است که برای حذف واسطه‌های غیرضروری و غیرتکنولوژیکی لازم است: واسطه‌هایی که روز آن‌ها نهایتاً فرا رسیده است. به طور کلی، ارزیابی یک زبان برنامه‌نویسی باید با توجه به نیازها و شرایط پروژه‌ها صورت گیرد. سی‌پلاس‌پلاس در بسیاری از مواقع یک انتخاب عالی است و اگرچه ممکن است برخی نقدهایی وجود داشته باشد، اما این نقدها به طور کلی به عنوان چالش‌ها و به چشم‌گیرترین قابلیت‌های این زبان می‌توانند مطرح شوند. نتیجهٔ نهایی زبان برنامه‌نویسی سی‌پلاس‌پلاس احتمالاً محبوب‌ترین زبان برنامه‌نویسی در دنیای توسعه نرم‌افزار است. توسعه بلاکچین نیز شامل کدنویسی است و برخی از بلاکچین‌ها مانند شبکه بیت‌کوین از سی‌پلاس‌پلاس به عنوان زبان برنامه‌نویسی خود استفاده می‌کنند. ساتوشی ناکاموتو، خالق بیت‌کوین، این زبان را به دلیل امنیت و قابلیت مدیریت منابع تراکنش‌ها و عملیات قراردادهای هوشمند انتخاب کرد. به علاوه، این زبان به توسعه‌دهندگان امکان ادغام وظایف موازی و غیرموازی را به صورت بی‌نقص فراهم می‌کند. مصرف بهینهٔ منابع و رعایت موضوع انرژی سبز مهم است؛ همچنین، این زبان به‌طور منظم به‌روزرسانی می‌شود و ابزارهای تجزیه و تحلیل و اشکال‌زدائی متنوعی دارد که همگی به بهبود عملکرد آن کمک می‌کنند. نگاه به بهترین مزایای زبان در بلاکچین، به همه اجازه می‌دهد که درک کنند چرا ساتوشی ناکاموتو این زبان را در ایجاد بلاکچین بیت‌کوین انتخاب کرد. ایجاد بلاک‌چین ناکاموتو یکی از پربارترین اختراعات فناوری مالی زمان ما را ایجاد کرد که شفافیت، تمرکززدایی و ماندگاری تراکنش ها و داده ها را تقویت کرد. ارز متمرکز بر بلاک‌چین نیز همچنان پر استفاده ترین، قابل اعتمادترین، ارز دیجیتال پرسود و چشم انداز سرمایه گذاری است و در پشت ساخت این فناوری غول زبان‌های برنامه‌نویسی آن را به بهترین نوع خود تبدیل و در همین راستا در مسیر توسعه و پیشرفت هدایت می‌کند.
  1. نمایش فعالیت های بیشتر
×
×
  • جدید...