سؤال

على برنامج التحويل البرمجي Visual Studio 2005 C++, ، أتلقى التحذير التالي عندما يستخدم الكود الخاص بي com.fopen ومثل هذه الدعوات.

1>foo.cpp(5) : warning C4996: 'fopen' was declared deprecated
1>        c:\program files\microsoft visual studio 8\vc\include\stdio.h(234) : see declaration of 'fopen'
1>        Message: 'This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.'

كيف يمكنني منع هذا؟

هل كانت مفيدة؟

المحلول

يبدو أن Microsoft قد أوقفت الكثير من المكالمات التي تستخدم المخازن المؤقتة لتحسين أمان التعليمات البرمجية.ومع ذلك، فإن الحلول التي يقدمونها ليست محمولة.على أية حال، إذا لم تكن مهتمًا باستخدام الإصدار الآمن من مكالماتهم (مثل fopen_s)، تحتاج إلى وضع تعريف ل _CRT_SECURE_NO_DEPRECATE قبل ملفات الرأس المضمنة.على سبيل المثال:

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

يمكن أيضًا إضافة توجيه المعالج المسبق إلى إعدادات المشروع الخاص بك للتأثير على كافة الملفات الموجودة ضمن المشروع.للقيام بذلك أضف _CRT_SECURE_NO_DEPRECATE ل خصائص المشروع -> خصائص التكوين -> C/C++ -> المعالج الأولي -> تعريفات المعالج الأولي.

نصائح أخرى

حسنًا، يمكنك إضافة:

#pragma warning (disable : 4996)

قبل استخدام fopen، ولكن هل فكرت في استخدام fopen_s كما يقترح التحذير؟يقوم بإرجاع رمز خطأ يسمح لك بالتحقق من نتيجة استدعاء الوظيفة.

المشكلة في مجرد تعطيل تحذيرات الوظائف المهملة هي أن Microsoft قد تقوم بإزالة الوظيفة المعنية في إصدار أحدث من CRT، مما يؤدي إلى كسر التعليمات البرمجية الخاصة بك (كما هو مذكور أدناه في التعليقات، لن يحدث هذا في هذه الحالة مع fopen لأنه جزء من معايير C & C++ ISO).

هذا مجرد كون مايكروسوفت صفيق.يشير "موقوف" إلى ميزة لغوية قد لا يتم توفيرها في الإصدارات المستقبلية من اللغة القياسية/المكتبات القياسية، وفقًا لما قررته لجنة المعايير.فهو لا يعني، ولا ينبغي له أن يعني، "نحن، من جانب واحد، لا نعتقد أنه ينبغي عليك استخدامه"، بغض النظر عن مدى صحة هذه النصيحة.

إذا كان الرمز الخاص بك مخصصًا لنظام تشغيل مختلف (مثل Mac OS X وLinux)، فيمكنك استخدام ما يلي:

#ifdef _WIN32
#define _CRT_SECURE_NO_DEPRECATE
#endif

فكر في استخدام مكتبة قابلة للنقل مثل عفويا أو ال وقت تشغيل أباتشي المحمول.توفر هذه عادةً بدائل آمنة ومحمولة لمثل هذه المكالمات.وهذا أمر جيد أيضًا، لأن هذه المكالمات غير الآمنة مهملة في معظم البيئات الحديثة.

أنا أستخدم VisualStdio 2008.في هذه الحالة غالبا ما أقوم بتعيين Preprocessor Definitions

القائمة \ المشروع \ [اسم المشروع] الخصائص...البديل+F7

إذا قمت بالنقر فوق هذه القائمة أو اضغط على Alt + F7 في نافذة المشروع، يمكنك أن ترى "صفحات الملكية" نافذة او شباك.

ثم انظر القائمة على يسار النافذة.

خصائص التكوين \C/C++\المعالج المسبق

ثم أضف _CRT_SECURE_NO_WARNINGS ل \ تعريفات المعالجات الأولية.

إذا كنت تريد استخدامه على العديد من الأنظمة الأساسية، فيمكنك تعريف الاستخدام المعلق مثل:

#if defined(_MSC_VER) || defined(WIN32)  || defined(_WIN32) || defined(__WIN32__) \
                        || defined(WIN64)    || defined(_WIN64) || defined(__WIN64__) 

        errno_t err = fopen_s(&stream,name, "w");

#endif

#if defined(unix)        || defined(__unix)      || defined(__unix__) \
                        || defined(linux)       || defined(__linux)     || defined(__linux__) \
                        || defined(sun)         || defined(__sun) \
                        || defined(BSD)         || defined(__OpenBSD__) || defined(__NetBSD__) \
                        || defined(__FreeBSD__) || defined __DragonFly__ \
                        || defined(sgi)         || defined(__sgi) \
                        || defined(__MACOSX__)  || defined(__APPLE__) \
                        || defined(__CYGWIN__) 

        stream = fopen(name, "w");

#endif

بالنسبة لأولئك الذين يستخدمون إصدار Visual Studio 2017، يبدو أن تعريف المعالج المسبق المطلوب لتشغيل العمليات غير الآمنة قد تغير.استخدم بدلاً من ذلك:

#define _CRT_SECURE_NO_WARNINGS

سيتم تجميعها بعد ذلك.

تعد العديد من وظائف Microsoft الآمنة، بما في ذلك fopen_s()، جزءًا من C11، لذا يجب أن تكون محمولة الآن.يجب أن تدرك أن الوظائف الآمنة تختلف في سلوكيات الاستثناء وأحيانًا في قيم الإرجاع.بالإضافة إلى ذلك، عليك أن تدرك أنه على الرغم من أن هذه الوظائف موحدة، إلا أنها تعتبر خياري جزء من المعيار (الملحق K) الذي لا يتم تنفيذه على الأقل glibc (الافتراضي في Linux) وFreeBSD's libc.

ومع ذلك، حاربت هذه المشكلة لبضع سنوات.لقد قمت بنشر مجموعة أكبر من وحدات ماكرو التحويل هنا., ، بالنسبة لمشكلتك الفورية، ضع الكود التالي في ملف التضمين، وقم بتضمينه في كود المصدر الخاص بك:

#pragma once
#if !defined(FCN_S_MACROS_H)
   #define   FCN_S_MACROS_H

   #include <cstdio>
   #include <string> // Need this for _stricmp
   using namespace std;

   // _MSC_VER = 1400 is MSVC 2005. _MSC_VER = 1600 (MSVC 2010) was the current
   // value when I wrote (some of) these macros.

   #if (defined(_MSC_VER) && (_MSC_VER >= 1400) )

      inline extern
      FILE*   fcnSMacro_fopen_s(char *fname, char *mode)
      {  FILE *fptr;
         fopen_s(&fptr, fname, mode);
         return fptr;
      }
      #define fopen(fname, mode)            fcnSMacro_fopen_s((fname), (mode))

   #else
      #define fopen_s(fp, fmt, mode)        *(fp)=fopen( (fmt), (mode))

   #endif //_MSC_VER

#endif // FCN_S_MACROS_H

بالطبع لا يطبق هذا الأسلوب سلوك الاستثناء المتوقع.

أنا أيضا حصلت على نفس المشكلة.عندما أحاول إضافة مكتبة opencv

#include <opencv\cv.h>

لم أتلق أي تحذير بل خطأ.

error C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    c:\program files (x86)\opencv\build\include\opencv2\flann\logger.h  

لقد استخدمت أيضًا توجيهات المعالج المسبق كما ذكرنا.لكن ذلك لم يحل المشكلة.

لقد قمت بحلها عن طريق القيام بما يلي:

  • انتقل إلى الخصائص -> C/C++ -> الرؤوس المترجمة مسبقًا -> اختر عدم استخدام الرؤوس المترجمة مسبقًا في الرأس المترجم مسبقًا.
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top