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?
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 .
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).
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é.
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
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.
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.
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
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.
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.
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é.