fopen avertissement obsolète

Sur Visual Studio 2005 C++ compiler, je reçois l'avertissement suivant lorsque mon code utilise le fopen et de tels appels.

1>foo.cpp(5) : warning C4996: 'fopen' was declared deprecated
1>        c:program filesmicrosoft visual studio 8vcincludestdio.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.'

Comment puis-je empêcher cela?

57
demandé sur Leos313 2008-08-18 13:38:58

10 réponses

Il semble que Microsoft ait déprécié beaucoup d'appels qui utilisent des tampons pour améliorer la sécurité du code. Cependant, les solutions qu'ils fournissent ne sont pas portables. Quoi qu'il en soit, si vous n'êtes pas intéressé à utiliser la version sécurisée de leurs appels (comme fopen_s), vous devez placer une définition de _crt_secure_no_deprecate avant vos fichiers d'en-tête inclus. Par exemple:

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

La directive préprocesseur peut également être ajoutée aux paramètres de votre projet pour l'appliquer à tous les fichiers dans le cadre du projet. Pour ce faire, ajoutez _CRT_SECURE_NO_DEPRECATE à Propriétés du Projet - > Propriétés de Configuration - > C / C++ - > préprocesseur - > définitions de préprocesseur .

108
répondu Ashwin Nanjappa 2008-08-18 09:39:16

Eh bien, vous pouvez ajouter un:

#pragma warning (disable : 4996)

Avant d'utiliser fopen, mais avez-vous envisagé d'utiliser fopen_s comme l'avertissement le suggère? Il renvoie un code d'erreur vous permettant de vérifier le résultat de l'appel de fonction.

Le problème avec la désactivation des avertissements de fonction obsolètes est que Microsoft peut supprimer la fonction en question dans une version ultérieure du CRT, en cassant votre code (comme indiqué ci - dessous dans les commentaires, cela n'arrivera pas dans ce cas avec fopen car cela fait partie du C & C++ normes ISO).

23
répondu John Sibly 2014-09-18 13:40:40

C'est juste Microsoft étant effronté. "Obsolète" implique une fonctionnalité de langue qui peut ne pas être fournie dans les versions futures de la langue standard / bibliothèques standard, comme décrété par le Comité des normes. Cela ne signifie pas, ou ne devrait pas signifier, "nous, unilatéralement, ne pensons pas que vous devriez l'utiliser", peu importe à quel point ce conseil est fondé.

13
répondu tragomaskhalos 2008-11-12 17:34:49

Si votre code est destiné à un système d'exploitation différent (comme Mac OS X, Linux), vous pouvez utiliser ce qui suit:

#ifdef _WIN32
#define _CRT_SECURE_NO_DEPRECATE
#endif
8
répondu Magnetron 2015-02-20 23:02:21

Pensez à utiliser une bibliothèque de portabilité comme glibou le Apache Portable runtime. Ceux-ci fournissent généralement des alternatives sûres et portables aux appels comme ceux-ci. C'est une bonne chose aussi, car ces appels non sécurisés sont obsolètes dans la plupart des environnements modernes.

4
répondu Joseph Holsten 2008-09-18 11:15:58

J'utilise VisualStdio 2008. Dans ce cas je mets souvent Preprocessor Definitions

Menu \ Project \ [NomProjet] Propriétés... Alt + F7

Si vous cliquez sur ce menu ou appuyez sur Alt + F7 dans la fenêtre du projet, vous pouvez voir "pages de propriétés" fenêtre.

Puis voir le menu à gauche de la fenêtre.

Propriétés De Configuration \ C/C++ \ Préprocesseur

, Puis ajoutez _CRT_SECURE_NO_WARNINGS de \ Définitions de Préprocesseur.

3
répondu Bryant 2017-07-15 03:35:23

Si vous voulez qu'il soit utilisé sur de nombreuses plates-formes, vous pourriez aussi commenté l'utilisation définit comme:

#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
1
répondu JTIM 2015-02-24 09:57:23

Pour ceux qui utilisent la version Visual Studio 2017, il semble que la définition du préprocesseur requise pour exécuter des opérations non sécurisées ait changé. Utiliser à la place:

#define _CRT_SECURE_NO_WARNINGS

Il compilera alors.

1
répondu Marcelo Coronel 2017-03-20 16:03:40

De nombreuses fonctions sécurisées de Microsoft, y compris fopen_s(), font partie de C11, elles devraient donc être portables maintenant. Vous devez vous rendre compte que les fonctions sécurisées diffèrent dans les comportements d'exception et parfois dans les valeurs de retour. De plus, vous devez être conscient que bien que ces fonctions soient normalisées, c'est une partie optionnelle de la norme (Annexe K) qu'au moins glibc (par défaut sous Linux) et la libc de FreeBSD n'implémentent pas.

Cependant, j'ai combattu ce problème pendant quelques années. Je posté un plus grand ensemble de macros de conversion ici., Pour votre problème immédiat, placez le code suivant dans un fichier include, et l'inclure dans votre code source:

#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

Bien sûr, cette approche n'implémente pas le comportement d'exception attendu.

1
répondu riderBill 2017-08-28 10:53:11

J'ai aussi eu le même problème. Lorsque j'essaie d'ajouter la bibliothèque opencv

#include <opencv\cv.h>

Je n'ai pas reçu d'avertissement mais une erreur.

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  

J'ai également utilisé les directives du préprocesseur comme mentionné. Mais cela ne résout pas le problème.

Je l'ai résolu en faisant comme suit:

  • allez dans Propriétés -> C / C++ - > en-têtes précompilés - > choisissez de ne pas utiliser les en-têtes précompilés dans L'en-tête précompilé.
0
répondu Karthik_elan 2014-12-30 17:10:55