Domanda

SU Compilatore C++ di Visual Studio 2005, ricevo il seguente avviso quando il mio codice utilizza il file fopen e tali chiamate.

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

Come posso evitare questo?

È stato utile?

Soluzione

Sembra che Microsoft abbia deprecato molte chiamate che utilizzano buffer per migliorare la sicurezza del codice.Tuttavia, le soluzioni che forniscono non sono portatili.Ad ogni modo, se non sei interessato a utilizzare la versione sicura delle loro chiamate (come fopen_s), è necessario inserire una definizione di _CRT_SECURE_NO_DEPRECATE prima dei file di intestazione inclusi.Per esempio:

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

La direttiva del preprocessore può anche essere aggiunta alle impostazioni del progetto per applicarla a tutti i file del progetto.Per fare ciò aggiungi _CRT_SECURE_NO_DEPRECATE A Proprietà del progetto -> Proprietà di configurazione -> C/C++ -> Preprocessore -> Definizioni del preprocessore.

Altri suggerimenti

Beh potresti aggiungere un:

#pragma warning (disable : 4996)

prima di utilizzare fopen, ma hai considerato l'utilizzo di fopen_s come suggerisce l'avviso?Restituisce un codice di errore che consente di verificare il risultato della chiamata alla funzione.

Il problema semplicemente disabilitando gli avvisi sulle funzioni deprecate è che Microsoft potrebbe rimuovere la funzione in questione in una versione successiva del CRT, interrompendo il codice (come indicato di seguito nei commenti, ciò non accadrà in questo caso con fopen perché fa parte di gli standard ISO C e C++).

Questo è solo il comportamento sfacciato di Microsoft."Deprecato" implica una funzionalità linguistica che potrebbe non essere fornita nelle versioni future del linguaggio standard/librerie standard, come decretato dal comitato per gli standard.Non significa, o non dovrebbe significare, "noi, unilateralmente, non pensiamo che dovresti usarlo", non importa quanto fondato sia questo consiglio.

Se il tuo codice è destinato a un sistema operativo diverso (come Mac OS X, Linux), puoi utilizzare quanto segue:

#ifdef _WIN32
#define _CRT_SECURE_NO_DEPRECATE
#endif

Prendi in considerazione l'utilizzo di una libreria di portabilità come disinvolto o il runtime portatile di apache.Questi di solito forniscono alternative sicure e portatili a chiamate come queste.È anche una buona cosa, perché queste chiamate non sicure sono deprecate nella maggior parte degli ambienti moderni.

Sto usando VisualStdio 2008.In questo caso spesso imposto Preprocessor Definitions

Menu \ Progetto \ [NomeProgetto] Proprietà...Alt+F7

Se fai clic su questo menu o premi Alt + F7 nella finestra del progetto, puoi vedere "Pagine delle proprietà" finestra.

Quindi vedere il menu a sinistra della finestra.

Proprietà di configurazione \ C/C++ \ Preprocessore

Poi aggiungi _CRT_SECURE_NO_WARNINGS A \ Definizioni del preprocessore.

Se vuoi che venga utilizzato su molte piattaforme, potresti definire l'uso commentato come:

#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

Per coloro che utilizzano la versione di Visual Studio 2017, sembra che la definizione del preprocessore richiesta per eseguire operazioni non sicure sia cambiata.Utilizzare invece:

#define _CRT_SECURE_NO_WARNINGS

Verrà compilato quindi.

Molte delle funzioni sicure di Microsoft, incluso fopen_s(), fanno parte di C11, quindi ora dovrebbero essere portabili.Dovresti capire che le funzioni sicure differiscono nei comportamenti delle eccezioni e talvolta nei valori restituiti.Inoltre è necessario essere consapevoli del fatto che, sebbene queste funzioni siano standardizzate, si tratta di un file opzionale parte dello standard (Annex K) che almeno glibc (default su Linux) e libc di FreeBSD non implementano.

Tuttavia, ho combattuto questo problema per alcuni anni.Ho pubblicato un set più ampio di macro di conversione Qui., Per il tuo problema immediato, inserisci il seguente codice in un file di inclusione e includilo nel codice sorgente:

#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

Naturalmente questo approccio non implementa il comportamento di eccezione previsto.

Anch'io ho avuto lo stesso problema.Quando provo ad aggiungere la libreria opencv

#include <opencv\cv.h>

Non ho ricevuto un avviso ma un errore.

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  

Ho anche usato le direttive del preprocessore come menzionato.Ma questo non ha risolto il problema.

Ho risolto facendo come segue:

  • Vai a Proprietà -> C/C++ -> Intestazioni precompilate -> Scegli Non utilizzare intestazioni precompilate nell'intestazione precompilata.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top