2008-08-18 9 views
52

पर विजुअल स्टूडियो 2005 सी ++ कंपाइलर, मुझे निम्न चेतावनी मिलती है जब मेरा कोड fopen और ऐसी कॉल का उपयोग करता है।fopen deprecated चेतावनी

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.' 

मैं इस को कैसे रोकूं?

उत्तर

97

यह माइक्रोसॉफ्ट की तरह दिखता है जो बफ़र्स का उपयोग कोड सुरक्षा में सुधार करने के लिए कॉल के बहुत सारे त्याग दिया है। हालांकि, वे जो समाधान प्रदान कर रहे हैं वे पोर्टेबल नहीं हैं। वैसे भी, यदि आप उनकी कॉल के सुरक्षित संस्करण (जैसे fopen_s) का उपयोग करने में रुचि नहीं रखते हैं, तो आपको अपनी शामिल हेडर फ़ाइलों से पहले _CRT_SECURE_NO_DEPRECATE की परिभाषा डालना होगा। उदाहरण के लिए:

#define _CRT_SECURE_NO_DEPRECATE 
#include <stdio.h> 

पूर्वप्रक्रमक निर्देश भी परियोजना के तहत सभी फाइलों पर यह प्रभाव अपनी परियोजना सेटिंग्स में जोड़ा जा सकता। ऐसा करने के लिए _CRT_SECURE_NO_DEPRECATE से प्रोजेक्ट गुण -> कॉन्फ़िगरेशन गुण -> सी/सी ++ -> प्रीप्रोसेसर -> प्रीप्रोसेसर परिभाषा

+8

आप शायद इस यद्यपि की तरह कुछ करना चाहिए: _WIN32 #ifdef #define _CRT_SECURE_NO_DEPRECATE #endif # शामिल क्योंकि अन्य प्लेटफार्मों कि संकलन समय के दौरान परिभाषित जरूरत नहीं है। – markwatson

+2

हां वास्तव में काम किया। –

+1

@markwatson एक बेहतर गार्ड '#ifdef _MSC_VER' जांचना होगा। – MicroVirus

23

वैसे आप एक जोड़ सकते हैं:

#pragma warning (disable : 4996) 

इससे पहले कि आप fopen उपयोग करें, लेकिन आप fopen_s का उपयोग कर के रूप में चेतावनी का सुझाव पर विचार किया है? यह एक त्रुटि कोड देता है जो आपको फ़ंक्शन कॉल के परिणाम की जांच करने की अनुमति देता है।

केवल बहिष्कृत फ़ंक्शन चेतावनियों को अक्षम करने में समस्या यह है कि माइक्रोसॉफ्ट सीआरटी के बाद के संस्करण में प्रश्न में फ़ंक्शन को हटा सकता है, जो आपके कोड को तोड़ रहा है (जैसा टिप्पणियों में नीचे बताया गया है, यह इस उदाहरण में फॉपेन के साथ नहीं होगा क्योंकि यह सी & सी ++ आईएसओ मानकों का हिस्सा है)।

+31

"माइक्रोसॉफ्ट सीआरटी के बाद के संस्करण में प्रश्न में फ़ंक्शन को हटा सकता है" - यदि वे अब सी या सी ++ मानकों को लागू नहीं करना चाहते हैं। –

+3

कुछ लोग गैर-एमएस प्लेटफार्मों को भी लक्षित करते हैं। और इनमें से बहुत से कार्यों के साथ, वास्तव में एक अच्छी तरह से उल्लेखनीय सुरक्षा लाभ नहीं है। – sstn

+8

भविष्य के googlers के लिए: 'इस संदर्भ में, "बहिष्कृत" बस मतलब है कि एक समारोह के उपयोग की सिफारिश नहीं है; यह इंगित नहीं करता है कि फ़ंक्शन को सीआरटी से हटाया जाना निर्धारित है। '- [msdn] (http://msdn.microsoft.com/en-us/library/8ef0s5kh.aspx) ++++ – Navin

4

glib या apache portable runtime की तरह एक पोर्टेबिलिटी लाइब्रेरी का उपयोग पर विचार करें। ये आमतौर पर इन तरह की कॉल के लिए सुरक्षित, पोर्टेबल विकल्प प्रदान करते हैं। यह भी एक अच्छी बात है, क्योंकि इन असुरक्षित कॉलों को अधिकांश आधुनिक वातावरण में बहिष्कृत किया जाता है।

11

यह माइक्रोसॉफ्ट सिर्फ गालिया है। "बहिष्कृत" का अर्थ एक ऐसी भाषा सुविधा है जो मानक भाषा/मानक पुस्तकालयों के भविष्य के संस्करणों में प्रदान नहीं किया जा सकता है, जैसा मानकों समिति द्वारा निर्धारित किया गया है। यह नहीं है, या इसका मतलब यह नहीं होना चाहिए, "हम, एकतरफा, ऐसा नहीं सोचते कि आपको इसका उपयोग करना चाहिए", इससे कोई फर्क नहीं पड़ता कि सलाह कितनी अच्छी तरह से स्थापित हुई है।

+14

अंग्रेजी शब्द "बहिष्कार" का अर्थ बिल्कुल दूसरी बात है: "हमें लगता है कि आपको इसका उपयोग नहीं करना चाहिए"। लेकिन कंप्यूटर पर निर्भरता में हाल ही में बहुत कमजोर अर्थ आया है, "इसका उपयोग करना बुद्धिमान नहीं हो सकता है, क्योंकि हम इसे हटाने की सोच रहे हैं, और हमने कुछ प्रदान किया है जो हम सोचते हैं बेहतर है"। –

7

आप कोड एक अलग ओएस के लिए है (जैसे मैक ओएस     X, लिनक्स) आप निम्नलिखित का उपयोग हो सकता है:

#ifdef _WIN32 
#define _CRT_SECURE_NO_DEPRECATE 
#endif 
0

मैं भी एक ही समस्या मिला है। जब मैं ओपनसीवी लाइब्रेरी

#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++ -> Precompiled हेडर -> precompiled शीर्ष लेख में Precompiled हेडर का उपयोग नहीं कर चुनें।
1

आप इसे कई प्लेटफार्मों पर इस्तेमाल किया जा करना चाहते हैं, तो आप के रूप में टिप्पणी की सकता उपयोग की तरह परिभाषित करता है:

#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 
+0

आपका जटिल #IF केवल प्लेटफ़ॉर्म को संबोधित करता है, संकलक संस्करण नहीं। कैसे '#if (परिभाषित (_MSC_VER) && (_MSC_VER> = 1600)) ... #ELSE ... 'इसमें सभी मामलों को शामिल करना चाहिए, है ना? – riderBill

+0

_MSC_VER = 1600 पहला संस्करण नहीं हो सकता है जो फॉपेन() इत्यादि को बहिष्कृत करता है। यह पहला संस्करण था जिसमें मुझे समस्या का सामना करना पड़ा। – riderBill

+0

ऐसा लगता है कि एमएसवीसी का पहला संस्करण (कुछ) सुरक्षित कार्यों 2005 के साथ था, _MSC_VER = 1400. – riderBill

1

माइक्रोसॉफ्ट के सुरक्षित कार्यों में से कई fopen_s(), सी 11 का हिस्सा है, इसलिए कर रहे हैं सहित वे अब पोर्टेबल होना चाहिए। आपको महसूस करना चाहिए कि सुरक्षित कार्य अपवाद व्यवहार और कभी-कभी वापसी मूल्यों में भिन्न होते हैं। इसके अतिरिक्त आपको यह पता होना चाहिए कि इन कार्यों को मानकीकृत किया गया है, लेकिन यह वैकल्पिक मानक (अनुलग्नक के) का हिस्सा है जो कम से कम ग्लिब (लिनक्स पर डिफ़ॉल्ट) और फ्रीबीएसडी का libc लागू नहीं होता है।

हालांकि, मैंने कुछ वर्षों से इस समस्या को लड़ा। मैं रूपांतरण मैक्रो here. के अपेक्षाकृत बड़े समूह पोस्ट, अपने तत्काल समस्या के लिए, एक में शामिल फ़ाइल में निम्न कोड डाल दिया, और अपने स्रोत कोड में शामिल हैं:

#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 

बेशक इस दृष्टिकोण की उम्मीद अपवाद व्यवहार को लागू नहीं करता है ।

+0

एमएस '_s सामान्य रूप से सी 11 सीमाओं की जांच इंटरफेस के समान नहीं हैं। कुछ में एक ही पाप है, कुछ नहीं करते हैं। चूंकि यह इंटरफ़ेस वैकल्पिक है, कुछ कार्यान्वयन इसका समर्थन करते हैं, क्योंकि यह ज्यादातर अनावश्यक है। और आपका कोड सी ++ है, सी नहीं जिसे आप पाठ में संदर्भित करते हैं। – Olaf

+0

@ ओलाफ: हम्म। मैं अपने अपवाद व्यवहार चेतावनी को इंगित करने के अलावा सीमाओं की जांच को संबोधित नहीं कर सकता। – riderBill

+0

आप सही हैं कि मैंने सी 11 मानक का उल्लेख किया (सी ++ 14 या 17 के विपरीत)। फ़ंक्शंस माइक्रोसॉफ्ट के सी ++ कंपाइलर्स के हाल के संस्करणों में उपलब्ध हैं। यह पता चला है कि एनेक्स के एमएसवीएस के बाहर व्यापक रूप से समर्थित नहीं है। जोनाथन लेफ्लर ने टिप्पणी की [https://stackoverflow.com/questions/858252/alternatives-to-ms-strncpy-s/35193374#35193374) कि एमएस संस्करण वास्तव में अनुलग्नक के विनिर्देशों से मेल नहीं खाते हैं। पोर्टेबिलिटी के लिए बहुत कुछ। – riderBill

1

जो लोग विजुअल स्टूडियो 2017 संस्करण का उपयोग कर रहे हैं, ऐसा लगता है कि असुरक्षित संचालन चलाने के लिए आवश्यक प्रीप्रोसेसर परिभाषा बदल गई है। इसके बजाए उपयोग करें:

#define _CRT_SECURE_NO_WARNINGS 

यह तब संकलित होगा। VisualStdio 2008 का उपयोग कर

3

I'am इस मामले में मैं अक्सर सेट Preprocessor Definitions

मेनू \ परियोजना \ [ProjectName] गुण ... Alt + एफ 7

हैं इस मेनू पर क्लिक करें या प्रोजेक्ट विंडो में Alt + F7 दबाएं, आप "संपत्ति पृष्ठ" विंडो देख सकते हैं।

फिर विंडो के बाईं ओर मेनू देखें।

विन्यास गुण \ C/C++ \ प्रीप्रोसेसर

फिर \ प्रीप्रोसेसर परिभाषाएँको _CRT_SECURE_NO_WARNINGS जोड़ें।

+0

कृपया इसे पहले देखें [जवाब कैसे दें ] (https://stackoverflow.com/help/how-to-answer) इस प्रश्न का उत्तर पहले दिया गया है, जाहिर है, आप यहां अपना उत्तर जोड़ सकते हैं। लेकिन आपको उत्तर देने से पहले कुछ बिंदुओं को समझने की आवश्यकता है। सबसे पहले, एक उत्तर जोड़ें जो पहले एक ही कोड या सुझाव के साथ जोड़ा गया है। दूसरा, उपयोगकर्ता ने बहुत ही जटिल उत्तर नहीं दिया है यदि उपयोगकर्ता ने विशेष रूप से समस्या के बारे में पूछा है और उसे हल करने के लिए उसे क्या चाहिए। तीसरा, यदि आप कोई टिप्पणी जोड़ सकते हैं तो आप एक टिप्पणी जोड़ सकते हैं आप कुछ भी सुझाव देना चाहते हैं उत्तर या प्रश्न एनजी। –

संबंधित मुद्दे