رفتن به مطلب
جامعه‌ی برنامه‌نویسان مُدرن ایران
کامبیز اسدزاده

رفع مشکل مقدار بازگشتی ماکروی cplusplus__

پست های پیشنهاد شده

سلام، مدتی بود که نسخه‌ی ۲۰۱۷ کامپایلر MSVC با مشکل عدم بازگشت مقدار صحیح از نسخه‌ی استاندارد زبان مواجه بود. هرچند توسط توسعه دهندگان این مشکل به مایکروسافت گزارش داده شده بود اما ظاهراً مشکل همچنان پا برجاست.

و اما مشکل، کد زیر را با کامپایلر MSVC2017 اجرا کنید:

#include <iostream>

int main()
{
	std::cout << __cplusplus << std::endl;
	std::cin.get();
	return 0;
}

اگر دقت کنید مقدار بازگشتی این کد 199711خواهد بود. در حالی که باید  مقدار بازگشتی آن با توجه به استاندارد زبان باید یکی از دو مقدار 201402L یا 201403 باشد. برای حل این مورد من پچی را فراهم کردم که می‌تونید این مشکل رو حل کنید. علاوه بر این یک سری ماکرو نویسی جزئی انجام شده که با دقت بیشتر و مقدار بازگشتی از نام خود کامپایلر را برای شما ارائه دهد.

طبق اصلاحیه کد دستوری آن به صورت زیر خواهد که تکه‌ای از کد‌های یکی از پروژه‌های من به نام Genesis بود که حالا اینجا به اشتراک گذاشتمش:

#include <iostream>

using namespace std;

#include "macro.h"

int main()
{
    Macro mc;
    cout << "Hello World!" << endl;
    cout << "C++ Standard Version (MSVC) : " << __cplusplus << endl;
    cout << "C++ Standard Version (with bug fix in MSVC : " << __GENESIS_CPP_VALUE__ << endl;
    cout << "C++ Standard Version (with bug fix in MSVC using function: " << mc.get__cplusplus(false) << endl;
    cout << "Compiler name using flag true: " << mc.get__cplusplus(true) << endl;
    return 0;
}

خروجی:

Hello World!
C++ Standard Version (MSVC) : 199711
C++ Standard Version (with bug fix in MSVC : 201703
C++ Standard Version (with bug fix in MSVC using function: 201703
Compiler name using flag true: MSVC++

برای دریافت این اصلاحیه به مخزن آن مراجعه نمایید.

  • پسندیدن 3

به اشتراک گذاری این ارسال


لینک به ارسال
به اشتراک گذاری در سایت های دیگر

توی تنظیمات نباید ست بشه که استاندارد کامپایل C++11 هست؟ یعنی پیش‌فرض‌ش C++98 هست یا صرفاً پیاده‌سازی ماکرو باگ داره؟

به اشتراک گذاری این ارسال


لینک به ارسال
به اشتراک گذاری در سایت های دیگر
در 33 دقیقه قبل، سروش ربیعی گفته است :

توی تنظیمات نباید ست بشه که استاندارد کامپایل C++11 هست؟ یعنی پیش‌فرض‌ش C++98 هست یا صرفاً پیاده‌سازی ماکرو باگ داره؟

قبلاً گزارشی در مورد این مشکل داده شده که در این بخش خیلی‌ها بهش تاکید کردن، منم به گزارش خطا رو ارسال کردم.

مشکل صرفاً به مقدار بازگشتی ماکرو مربوط بود که تو هر تنظیماتی مثل (/std:c++latest /Zc) مقدار 199711L رو میداد. بر اساس گزارش حل شده‌ای که دادن احتمالاً در نسخه‌های اخیر حل شده باشه اما بعید می‌دونم به صورت پیشفرض و با همین تنظیمات استاندارد مشکلش حل شده باشه چون نتیجه‌ای ازش نگرفتم.

به اشتراک گذاری این ارسال


لینک به ارسال
به اشتراک گذاری در سایت های دیگر

برای ارسال دیدگاه یک حساب کاربری ایجاد کنید یا وارد حساب خود شوید

برای اینکه بتوانید دیدگاهی ارسال کنید نیاز دارید که کاربر سایت شوید

ایجاد یک حساب کاربری

برای حساب کاربری جدید در سایت ما ثبت نام کنید. عضویت خیلی ساده است !

ثبت نام یک حساب کاربری جدید

ورود به حساب کاربری

دارای حساب کاربری هستید؟ از اینجا وارد شوید

ورود به حساب کاربری

  • کاربران آنلاین در این صفحه   0 کاربر

    هیچ کاربر عضوی،در حال مشاهده این صفحه نیست.

  • مطالب مشابه

    • توسط کامبیز اسدزاده
      تعریف ماکرو
      یک ماکرو به عنوان یک قطعه کدی (رشته‌ای) است که به آن نام مشخصی داده شده است. قطعه کد مربوطه می‌تواند شامل رشته، عدد، شیء، تابع و دیگر موارد باشد. زمانی که از این نام استفاده شود آن را با محتوای موجود در ماکرو جایگزین می‌کند. به طور کلی دو نوع ماکرو وجود دارد Object-Like (شیء مانند) برای استفاده در زمانی که محتوا شامل اشیاء باشد و ‌Function-Like (تابع مانند) نیز زمانی مورد استفاده قرار می‌گیرد که شامل تابع می‌باشد.
      /* object-like macro */ #define <identifier> <replacement token list> /* function-like macro, note parameters */ #define <identifier>(<parameter list>) <replacement token list> نکته: ایجاد یک ماکروی سفارشی توسط دستور #define انجام می‌شود.
      /* create the macro */ #define <identifier> نکته: ماکرو‌های ایجاد شده توسط دستور #undef می‌توانند حذف شوند.
      /* delete the macro */ #undef <identifier> نکته: ماکرو‌ها علاوه بر اینکه می‌توانند توسط کاربر (توسعه‌دهنده) سفارشی ساخته شوند، همچنین از قبل به صورت از پیش تعریف شده برای انواع سیستم‌عامل‌ها، معماری‌ها و دیگر منظور‌ها ساخته شده اند که تحت استاندارد‌های کامپایلر‌ها متفاوت عمل می‌کنند.
       
      ماکرو‌ از نوع شیء (Object-Like)
      یک ماکرو از نوع شیء شناسه‌ی ساده‌ای است که با یک قطعه کد جایگزین می‌شود. آن را شیء مانند می‌نامند زیرا، به نظر می‌رسد یک شیء از نوع داده در آن مورد استفاده قرار می‌گیرد. معمولاً آن‌ها از نام‌های نمادین برای ثابت‌های عددی استفاده می‌شود.
      #define BUFFER_SIZE 1024 در کد فوق ماکروی BUFFER_SIZE دستور #define را دنبال می‌کند و مقدار ۱۰۲۴ را به عنوان مقدار آن در نظر می‌گیرد. در مثال زیر می‌توانید نحوه‌ی استفاده از یک ماکروی سفارشی از نوع شیء (Object-Like) را مشاهده کنید.
      #include <iostream> using namespace std; #define BUFFER_SIZE 1024 int main() { cout << "Buffer Size is : " << BUFFER_SIZE << endl; return 0; } ماکرو‌ از نوع تابع (Function-Like)
      همچنین شما می‌توانید از ماکرو‌ها مانند صدا زدن یک تابع استفاده کنید. این نوع ماکرو‌ها Function-Like هستند. برای تعریف این نوع شما باید از دستور پیش‌پردازنده‌ی #define استفاده کرده و دو پرانتز ر بلافاصله پس از نام ماکرو قرار دهید. در مثال زیر ماکرویی با نام Maximum را برای محاسبه‌ی بزرگترین عدد ورودی پیاده سازی کرده‌ایم.
      #include <iostream> using namespace std; #define Maximum( a, b ) a > b ? a : b int main() { int x = 4; int y = 9; int z = Maximum( x, y ); cout << "Result : " << z << endl; return 0; } نسخه‌ی معمولی آن می‌تواند به شکل زیر باشد.
      #include <iostream> using namespace std; int Maximum (int a, int b) { if (a > b) return a; else return b; } int main() { int x = 4; int y = 9; int z = Maximum( x, y ); cout << "Result : " << z << endl; return 0; } بعضی از موارد در حوزه‌ی سفارشی سازی ماکرو‌ها می‌تواند به صورت سلیقه‌ای و نسبت به نوع پروژه تعریف شوند. برای مثال قرار است در برنامه‌ای نوع اولویت اشکال‌زدائی را مشخص کنیم.
      #include <iostream> using namespace std; #define DEBUG # if defined (DEBUG) # define DEBUG_LEVEL 5 #endif # if DEBUG_LEVEL < 3 # define DLEVEL "Low Level" # elif DEBUG_LEVEL > 3 # define DLEVEL "High level" #endif int main() { cout << "Debug level is : " << DLEVEL; return 0; } در کد بالا توسط پیش پردزنده‌ی #define و پیش پردازنده‌‌های شرطی #if و #elif و #endif حالتی را ایجاد کرده‌ایم که با مشخص سازی درجه‌ی مشخصه DEBUG_LEVEL نتیجه‌ی آن اعلام خواهد شد.
       
      ماکرو‌های از پیش تعریف شده
      بسیاری از ماکرو‌های از پیش تعریف شده توسط کامپایلر‌ها و شرکت‌های سازنده وجود دارد که در توسعه بسیار مفید و کاربردی هستند. برای مثال اگر نیاز باشد کد شما بر اساس نوع پلتفرمی که بر روی آن اجرا می‌شود واکنش متفاوتی را انجام دهد نیاز خواهد بود تا از چنین ماکرو‌های پرکاربری استفاده کنید.
      مثال‌های زیر برخی از ماکرو‌های از پیش تعریف شده بر اساس استاندارد ISO را معرفی می‌کند.
      استاندارد‌های زبان
      نوع : __STDC__ تعریف شده برای استاندارد‌های ANSI X3.159-1989 | ISO/IEC 9899:1990 نوع : __STDC_VERSION__ تعریف شده C برای استاندارد‌های  ISO/IEC 9899-1:1994 | ISO/IEC 9899:1999 | ISO/IEC 9899:2011 نوع : __cplusplus تعریف شده ++C برای استاندارد‌های ISO/IEC 14882:1998 | ISO/IEC 14882:2011 | ISO/IEC 14882:2017 | ISO/IEC 14882:2014 نوع : __cplusplus_cli تعریف شده برای ECMA-372 نوع : __embedded_cplusplus تعریف شده برای پلتفرم‌های امبد در Embedded C++ یک مثال از کاربرد استاندارد‌های C تحت ماکرو‌های از پیش تعریف شده:
      #if defined(__STDC__) # define PREDEF_STANDARD_C_1989 # if defined(__STDC_VERSION__) # if (__STDC_VERSION__ >= 199409L) # define PREDEF_STANDARD_C_1994 # endif # if (__STDC_VERSION__ >= 199901L) # define PREDEF_STANDARD_C_1999 # endif # endif #endif مثال‌های زیر برخی از ماکرو‌های از پیش تعریف شده در پلتفرم‌های مختلف را معرفی می‌کند.
      پلتفرم ویندوز‌ دسکتاپ (Windows)
      نوع : _WIN16 تعریف شده برای پلتفرم‌های ۱۶ بیتی نوع : _WIN32 تعریف شده برای پلتفرم‌های ۳۲ بیتی نوع : _WIN64 تعریف شده برای پلتفرم‌های ۶۴ بیتی نوع : __WIN32__ تعریف شده برای پلتفرم‌های ۳۲ بیتی توسط کامپایلر‌های Borland C++ نوع : __TOS_WIN__ تعریف شده برای پلتفرم‌های ویندوز توسط xlC نوع : __WINDOWS__ تعریف شده برای پلتفرم‌های ویندوز توسط Watcom C/C++ پلتفرم ویندوز‌ اِمبِد (Windows CE)
      نوع : _WIN32_WCE تعریف شده برای پلتفرم‌‌های ویندوز ۳۲ بیتی در اِِمبِد نوع : WIN32_PLATFORM_ تعریف شده توسط Embedded Visual Studio C++ پلتفرم یونیکس مکینتاش (Unix macOS)
      نوع : macintosh تعریف شده نسخه‌های macOS نوع : Macintosh تعریف شده برای نسخه‌های macOS نوع : __APPLE__ تعریف شده برای Mac OS X توسط GNU C and Intel C++ نوع : __MACH__ تعریف شده برای Mac OS X توسط GNU C and Intel C++ پلتفرم لینوکس - کرنل (Linux Kernel)
      نوع : __linux__ تعریف شده برای کرنل لینوکس نوع : linux تعریف شده برای  کرنل لینوکس - منسوخ شده (سازگار نیست با POSIX) نوع : __linux تعریف شده برای کرنل لینوکس - منسوخ شده (سازگار نیست با POSIX) پلتفرم اندروید (Android)
      نوع : __ANDROID__ تعریف شده برای اندروید پلتفرم یونیکس بی‌اِ‌س‌دی (Unix BSD)
      نوع : __FreeBSD__ تعریف شده برای FreeBSD نوع : __NetBSD__ تعریف شده برای NetBSD نوع : __OpenBSD__ تعریف شده برای OpenBSD نوع : __bsdi__ تعریف شده برای BSDI نوع : __DragonFly__ تعریف شده برای Dragon Fly پلتفرم کیو‌اِن‌ایکس (QNX)
      نوع : __QNX__ تعریف شده برای نسخه‌های QNX 4.x نوع : __QNXNTO__ تعریف شده برای نسخه‌های QNX 4.x  
      نکته :  این مقاله ادامه دارد...
    • توسط GornerLabo
      سلام خدمت اساتید محترم . در مورد qint64 میخواستم اطلاعاتی کسب کنم. برای چه مواردی در برنامه نویسی با Qt استفاده می شود ؟
      با تشکر.
    • توسط GornerLabo
      ماکرو در فناوری Qt Quick به چه معناست و چه کاربردی دارد؟ 
×