Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Votre code utilise une fonction, un membre de classe, une variable ou un typedef marqué comme déconseillé. Les symboles sont déconseillés à l’aide d’un __declspec(deprecated) modificateur ou de l’attribut C++14 [[deprecated]] . Le message d’avertissement C4996 réel est spécifié par le modificateur ou l’attribut deprecated de la déclaration.
Important
Cet avertissement est toujours un message délibéré de l’auteur du fichier d’en-tête qui déclare le symbole. N’utilisez pas le symbole déconseillé sans comprendre les conséquences.
Remarques
De nombreuses fonctions, fonctions membres, modèles de fonction et variables globales dans les bibliothèques Visual Studio sont déconseillées. Certains, tels que POSIX et les fonctions spécifiques à Microsoft, sont déconseillés, car ils ont maintenant un autre nom préféré. Certaines fonctions de bibliothèque runtime C sont déconseillées, car elles sont non sécurisées et ont une variante plus sécurisée. D’autres sont déconseillées parce qu’elles sont obsolètes. Les messages de dépréciation incluent généralement un remplacement suggéré pour la fonction déconseillée ou la variable globale.
L’option /sdl du compilateur (Activer des vérifications de sécurité supplémentaires) élève cet avertissement à une erreur.
Désactiver l’avertissement
Pour résoudre un problème C4996, nous vous recommandons généralement de modifier votre code. Utilisez plutôt les fonctions suggérées et les variables globales. Si vous devez utiliser les fonctions ou variables existantes pour des raisons de portabilité, vous pouvez désactiver l’avertissement.
Désactiver l’avertissement pour une ligne de code spécifique
Pour désactiver l’avertissement pour une ligne de code spécifique, utilisez le warning pragma. #pragma warning(suppress : 4996)
Désactiver l’avertissement dans un fichier
Pour désactiver l’avertissement dans un fichier pour tout ce qui suit, utilisez le pragma d’avertissement. #pragma warning(disable : 4996)
Désactiver l’avertissement dans les builds de ligne de commande
Pour désactiver l’avertissement globalement dans les builds de ligne de commande, utilisez l’option /wd4996 de ligne de commande.
Désactiver l’avertissement d’un projet dans Visual Studio
Pour désactiver l’avertissement d’un projet entier dans l’IDE Visual Studio :
Ouvrez le dialogue Pages de propriétés du projet. Pour plus d’informations sur l’utilisation de la boîte de dialogue Pages de propriétés, consultez Pages de propriétés.
Sélectionnez la page propriétés>de configuration C/C++>Propriétés avancées .
Modifiez la propriété Désactiver les avertissements spécifiques pour ajouter
4996. Choisissez OK pour appliquer vos modifications.
Désactiver l’avertissement à l’aide de macros de préprocesseur
Vous pouvez également utiliser des macros de préprocesseur pour désactiver certaines classes spécifiques d’avertissements de dépréciation utilisés dans les bibliothèques. Ces macros sont décrites ci-dessous.
Pour définir une macro de préprocesseur dans Visual Studio :
Ouvrez le dialogue Pages de propriétés du projet. Pour plus d’informations sur l’utilisation de la boîte de dialogue Pages de propriétés, consultez Pages de propriétés.
Développez le préprocesseur C/C++ > des propriétés > de configuration.
Dans la propriété Preprocessor Definitions , ajoutez le nom de la macro. Choisissez OK pour enregistrer, puis regénérer votre projet.
Pour définir une macro uniquement dans des fichiers sources spécifiques, ajoutez une ligne comme #define EXAMPLE_MACRO_NAME avant toute ligne qui inclut un fichier d’en-tête.
Voici quelques-unes des sources courantes des avertissements et erreurs C4996 :
Noms de fonctions POSIX
Le nom POSIX de cet élément est déconseillé. Utilisez plutôt le nom conforme ISO C et C++ :
new-name. Pour plus d’informations, consultez l’aide en ligne.
Microsoft a renommé certaines fonctions de bibliothèque spécifiques à POSIX et Microsoft dans le CRT pour se conformer aux contraintes C99 et C++03 sur les noms réservés et globaux définis par l’implémentation. Seuls les noms sont déconseillés, et non les fonctions elles-mêmes. Dans la plupart des cas, un trait de soulignement de début a été ajouté au nom de la fonction pour créer un nom conforme. Le compilateur émet un avertissement de dépréciation pour le nom de la fonction d’origine et suggère le nom préféré.
Pour résoudre ce problème, nous vous recommandons généralement de modifier votre code pour utiliser les noms de fonction suggérés à la place. Toutefois, les noms mis à jour sont spécifiques à Microsoft. Si vous devez utiliser les noms de fonctions existants pour des raisons de portabilité, vous pouvez désactiver ces avertissements. Les fonctions sont toujours disponibles dans la bibliothèque sous leurs noms d’origine.
Pour désactiver les avertissements de dépréciation pour ces fonctions, définissez la macro _CRT_NONSTDC_NO_WARNINGSde préprocesseur. Vous pouvez définir cette macro sur la ligne de commande en incluant l’option /D_CRT_NONSTDC_NO_WARNINGS.
Fonctions de bibliothèque CRT non sécurisées
Cette fonction ou cette variable peut être dangereuse. Envisagez plutôt d’utiliser
safe-version. Pour désactiver la dépréciation, utilisez _CRT_SECURE_NO_WARNINGS. Pour plus d’informations, consultez l’aide en ligne.
Microsoft a déconseillé certaines fonctions de bibliothèque standard CRT et C++ standard, car des versions plus sécurisées sont disponibles. La plupart des fonctions déconseillées autorisent l’accès en lecture ou en écriture non vérifié aux mémoires tampons. Leur mauvaise utilisation peut entraîner des problèmes de sécurité graves. Le compilateur émet un avertissement de dépréciation pour ces fonctions et suggère la fonction préférée.
Pour résoudre ce problème, nous vous recommandons d’utiliser la fonction ou la variable safe-version à la place. Parfois, vous ne pouvez pas, pour des raisons de portabilité ou de compatibilité descendante. Vérifiez soigneusement qu’il n’est pas possible qu’un remplacement de mémoire tampon ou une surread se produise dans votre code. Ensuite, vous pouvez désactiver l’avertissement.
Pour désactiver les avertissements de dépréciation pour ces fonctions dans le CRT, définissez _CRT_SECURE_NO_WARNINGS.
Pour désactiver les avertissements concernant les variables globales déconseillées, définissez _CRT_SECURE_NO_WARNINGS_GLOBALS.
Pour plus d’informations sur ces fonctions déconseillées et les globals, consultez Fonctionnalités de sécurité dans les bibliothèques CRT et Safe : Bibliothèque C++ Standard.
Fonctions de bibliothèque standard non sécurisées
'std ::
function_name::_Unchecked_iterators ::_Deprecate' Appel à std ::function_nameavec des paramètres qui peuvent être dangereux - cet appel s’appuie sur l’appelant pour vérifier que les valeurs passées sont correctes. Pour désactiver cet avertissement, utilisez -D_SCL_SECURE_NO_WARNINGS. Consultez la documentation sur l’utilisation de Visual C++ « Itérateurs vérifiés »
Dans Visual Studio 2015, cet avertissement s’affiche dans les builds de débogage, car certains modèles de fonction de bibliothèque standard C++ ne vérifient pas l’exactitude des paramètres. Souvent, c’est parce que les informations insuffisantes sont disponibles pour la fonction pour vérifier les limites du conteneur. Ou, étant donné que les itérateurs peuvent être utilisés de manière incorrecte avec la fonction. Cet avertissement vous aide à identifier ces fonctions, car elles peuvent être source de trous de sécurité graves dans votre programme. Pour plus d’informations, consultez itérateurs vérifiés.
Par exemple, cet avertissement s’affiche en mode Débogage si vous passez un pointeur d’élément à std::copy, au lieu d’un tableau brut. Pour résoudre ce problème, utilisez un tableau déclaré de manière appropriée, afin que la bibliothèque puisse vérifier les étendues du tableau et effectuer la vérification des limites.
// C4996_copyarray.cpp
// compile with: cl /c /W4 /D_DEBUG C4996_copyarray.cpp
#include <algorithm>
void example(char const * const src) {
char dest[1234];
char * pdest3 = dest + 3;
std::copy(src, src + 42, pdest3); // C4996
std::copy(src, src + 42, dest); // OK, copy can tell that dest is 1234 elements
}
Plusieurs algorithmes de bibliothèque standard ont été mis à jour pour avoir des versions « double plage » en C++14. Si vous utilisez les versions à double plage, la deuxième plage fournit la vérification des limites nécessaires :
// C4996_containers.cpp
// compile with: cl /c /W4 /D_DEBUG C4996_containers.cpp
#include <algorithm>
bool example(
char const * const left,
const size_t leftSize,
char const * const right,
const size_t rightSize)
{
bool result = false;
result = std::equal(left, left + leftSize, right); // C4996
// To fix, try this form instead:
// result = std::equal(left, left + leftSize, right, right + rightSize); // OK
return result;
}
Cet exemple illustre plusieurs autres façons dont la bibliothèque standard peut être utilisée pour vérifier l’utilisation de l’itérateur et lorsque l’utilisation non vérifiée peut être dangereuse :
// C4996_standard.cpp
// compile with: cl /EHsc /W4 /MDd C4996_standard.cpp
#include <algorithm>
#include <array>
#include <iostream>
#include <iterator>
#include <numeric>
#include <string>
#include <vector>
using namespace std;
template <typename C> void print(const string& s, const C& c) {
cout << s;
for (const auto& e : c) {
cout << e << " ";
}
cout << endl;
}
int main()
{
vector<int> v(16);
iota(v.begin(), v.end(), 0);
print("v: ", v);
// OK: vector::iterator is checked in debug mode
// (i.e. an overrun triggers a debug assertion)
vector<int> v2(16);
transform(v.begin(), v.end(), v2.begin(), [](int n) { return n * 2; });
print("v2: ", v2);
// OK: back_insert_iterator is marked as checked in debug mode
// (i.e. an overrun is impossible)
vector<int> v3;
transform(v.begin(), v.end(), back_inserter(v3), [](int n) { return n * 3; });
print("v3: ", v3);
// OK: array::iterator is checked in debug mode
// (i.e. an overrun triggers a debug assertion)
array<int, 16> a4;
transform(v.begin(), v.end(), a4.begin(), [](int n) { return n * 4; });
print("a4: ", a4);
// OK: Raw arrays are checked in debug mode
// (i.e. an overrun triggers a debug assertion)
// NOTE: This applies only when raw arrays are
// given to C++ Standard Library algorithms!
int a5[16];
transform(v.begin(), v.end(), a5, [](int n) { return n * 5; });
print("a5: ", a5);
// WARNING C4996: Pointers cannot be checked in debug mode
// (i.e. an overrun triggers undefined behavior)
int a6[16];
int * p6 = a6;
transform(v.begin(), v.end(), p6, [](int n) { return n * 6; });
print("a6: ", a6);
// OK: stdext::checked_array_iterator is checked in debug mode
// (i.e. an overrun triggers a debug assertion)
int a7[16];
int * p7 = a7;
transform(v.begin(), v.end(),
stdext::make_checked_array_iterator(p7, 16),
[](int n) { return n * 7; });
print("a7: ", a7);
// WARNING SILENCED: stdext::unchecked_array_iterator
// is marked as checked in debug mode, but it performs no checking,
// so an overrun triggers undefined behavior
int a8[16];
int * p8 = a8;
transform( v.begin(), v.end(),
stdext::make_unchecked_array_iterator(p8),
[](int n) { return n * 8; });
print("a8: ", a8);
}
Si vous avez vérifié que votre code ne peut pas avoir d’erreur de dépassement de mémoire tampon, vous pouvez désactiver cet avertissement. Pour désactiver les avertissements pour ces fonctions, définissez _SCL_SECURE_NO_WARNINGS.
Itérateurs vérifiés activés
C4996 peut également se produire si vous n’utilisez pas d’itérateur vérifié lorsqu’il _ITERATOR_DEBUG_LEVEL est défini comme 1 ou 2. Il est défini sur 2 par défaut pour les builds en mode débogage, et sur 0 pour les builds de vente au détail. Pour plus d’informations, consultez itérateurs vérifiés.
// C4996_checked.cpp
// compile with: /EHsc /W4 /MDd C4996_checked.cpp
#define _ITERATOR_DEBUG_LEVEL 2
#include <algorithm>
#include <iterator>
using namespace std;
using namespace stdext;
int main() {
int a[] = { 1, 2, 3 };
int b[] = { 10, 11, 12 };
copy(a, a + 3, b + 1); // C4996
// try the following line instead:
// copy(a, a + 3, checked_array_iterator<int *>(b, 3)); // OK
}
Code MFC ou ATL non sécurisé
C4996 peut se produire si vous utilisez des fonctions MFC ou ATL déconseillées pour des raisons de sécurité.
Pour résoudre ce problème, nous vous recommandons vivement de modifier votre code pour utiliser des fonctions mises à jour à la place.
Pour plus d’informations sur la suppression de ces avertissements, consultez _AFX_SECURE_NO_WARNINGS.
Fonctions et variables CRT obsolètes
Cette fonction ou cette variable a été remplacée par des fonctionnalités de bibliothèque ou de système d’exploitation plus récentes. Envisagez plutôt d’utiliser
new_item. Pour plus d’informations, consultez l’aide en ligne.
Certaines fonctions de bibliothèque et variables globales sont déconseillées comme obsolètes. Ces fonctions et variables peuvent être supprimées dans une version ultérieure de la bibliothèque. Le compilateur émet un avertissement de dépréciation pour ces éléments et suggère l’alternative préférée.
Pour résoudre ce problème, nous vous recommandons de modifier votre code pour utiliser la fonction ou la variable suggérée.
Pour désactiver les avertissements de dépréciation pour ces éléments, définissez _CRT_OBSOLETE_NO_WARNINGS. Pour plus d’informations, consultez la documentation relative à la fonction ou à la variable déconseillée.
Erreurs de marshaling dans le code CLR
C4996 peut également se produire lorsque vous utilisez la bibliothèque de marshaling CLR. Dans ce cas, C4996 est une erreur, et non un avertissement. L’erreur se produit lorsque vous utilisez marshal_as pour convertir entre deux types de données qui nécessitent une marshal_context classe. Vous pouvez également recevoir cette erreur lorsque la bibliothèque de marshaling ne prend pas en charge une conversion. Pour plus d’informations sur la bibliothèque de marshaling, consultez Vue d’ensemble du marshaling en C++.
Cet exemple génère l’erreur C4996, car la bibliothèque de marshaling nécessite un contexte pour effectuer une conversion d’un System::String en un const char *.
// C4996_Marshal.cpp
// compile with: /clr
// C4996 expected
#include <stdlib.h>
#include <string.h>
#include <msclr\marshal.h>
using namespace System;
using namespace msclr::interop;
int main() {
String^ message = gcnew String("Test String to Marshal");
const char* result;
result = marshal_as<const char*>( message );
return 0;
}
Exemple : fonction dépréciée définie par l’utilisateur
Vous pouvez utiliser l’attribut deprecated dans votre propre code pour avertir les appelants lorsque vous ne recommandez plus l’utilisation de certaines fonctions. Dans cet exemple, C4996 est généré à deux emplacements : un pour la ligne sur laquelle la fonction déconseillée est déclarée, et une pour la ligne sur laquelle la fonction est utilisée.
// C4996.cpp
// compile with: /W3
// C4996 warning expected
#include <stdio.h>
// #pragma warning(disable : 4996)
void func1(void) {
printf_s("\nIn func1");
}
[[deprecated]]
void func1(int) {
printf_s("\nIn func2");
}
int main() {
func1();
func1(1); // C4996
}