Avertissement du compilateur (niveau 3) C4996
Votre code utilise une fonction, un membre de classe, une variable ou un typedef marqué déconseillé. Les symboles sont déconseillés à l’aide d’un modificateur __declspec(deprecated)
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(-trice) du fichier d’en-tête qui déclare le symbole. N’utilisez pas le symbole déconseillé sans comprendre les conséquences.
Notes
De nombreuses fonctions, fonctions membres, modèles de fonctions et variables globales des 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 comprennent généralement une suggestion de remplacement de la fonction ou de la variable globale déconseillée.
L’option /sdl
(Activer des vérifications de sécurité supplémentaires) l’option du compilateur é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 pragmawarning
, #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 de ligne de commande /wd4996
.
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 de Propriétés de configuration>C/C++>Avancé.
Modifiez la propriété Désactiver les avertissements spécifiques pour ajouter
4996
. Choisissez OK pour appliquer vos modifications.
Désactivez l’avertissement à l’aide de macros de préprocesseur
Vous pouvez également utiliser des macros de préprocesseur pour désactiver certaines catégories 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 Propriétés de configuration>C/C++ > Préprocesseur.
Dans la propriété Définitions du préprocesseur, ajoutez le nom de la macro. Choisissez OK pour enregistrer, puis régénérez votre projet.
Pour définir une macro uniquement dans des fichiers source spécifiques, ajoutez une ligne comme #define EXAMPLE_MACRO_NAME
que avant toute ligne incluant un fichier d’en-tête.
Voici quelques-unes des sources courantes des avertissements et erreurs C4996 :
Noms de fonctions POSIX
The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name:
new-name.
See online help for details.
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, mais pas les fonctions elles-mêmes. Dans la plupart des cas, un trait de soulignement a été ajouté au nom de la fonction pour créer un nom conforme. Le compilateur émet un avertissement indiquant que le nom d’origine des fonctions sont déconseillés 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 déconseillant ces fonctions, définissez la macro de préprocesseur _CRT_NONSTDC_NO_WARNINGS
. Vous pouvez définir ce macro sur la ligne de commande en incluant l’option /D_CRT_NONSTDC_NO_WARNINGS
.
Fonctions non sûres de la bibliothèque CRT
This function or variable may be unsafe. Consider using
safe-version
instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.
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 indiquant que ces fonctions sont déconseillées 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 écrasement ou une lecture excessive de la mémoire tampon se produise dans votre code. Ensuite, vous pouvez désactiver l’avertissement.
Pour désactiver les avertissements déconseillant ces fonctions dans la bibliothèque CRT, définissez _CRT_SECURE_NO_WARNINGS
.
Pour désactiver les avertissements relatifs à des variables globales déconseillées, définissez _CRT_SECURE_NO_WARNINGS_GLOBALS
.
Pour plus d’informations sur ces fonctions déconseillées et les éléments globaux, consultez Fonctionnalités de sécurité dans les CRT et Bibliothèques sécurisées : bibliothèque standard C++.
Fonctions de bibliothèque standard non sécurisées
'std::
function_name
::_Unchecked_iterators::_Deprecate' Call to std::
function_name
with parameters that may be unsafe - this call relies on the caller to check that the passed values are correct. To disable this warning, use -D_SCL_SECURE_NO_WARNINGS. See documentation on how to use Visual C++ 'Checked Iterators'
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(-trice) 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(-trice) vérifié(e) lorsque _ITERATOR_DEBUG_LEVEL
est défini sur 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 également se produire si vous utilisez des fonctions MFC ou ATL qui ont été déconseillées pour des raisons de sécurité.
Pour résoudre ce problème, nous vous recommandons vivement de modifier votre code afin d’utiliser les fonctions mises à jour.
Pour savoir comment supprimer ces avertissements, voir _AFX_SECURE_NO_WARNINGS
.
Fonctions et variables obsolètes du CRT
This function or variable has been superseded by newer library or operating system functionality. Consider using
new_item
instead. See online help for details.
Certaines fonctions de la bibliothèque et certaines variables globales sont déconseillées, car elles sont obsolètes. Ces fonctions et variables sont susceptibles d’être supprimées dans une version future de la bibliothèque. Le compilateur émet un avertissement indiquant que ces éléments sont déconseillées et suggère l’alternative préférée.
Pour résoudre ce problème, nous vous recommandons de modifier votre code afin d’utiliser la fonction ou la variable suggérée.
Pour désactiver les avertissements déconseillant ces éléments, définissez _CRT_OBSOLETE_NO_WARNINGS
. Pour plus d’informations, consultez la documentation pour la fonction ou la variable déconseillée.
Marshaling des erreurs 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, plutôt qu’un avertissement. L’erreur se produit lorsque vous utilisez marshal_as
pour effectuer la conversion 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 de conversion en charge. Pour plus d’informations sur la bibliothèque de marshaling, consultez Overview of Marshaling in C++.
Cet exemple génère le message C4996, car la bibliothèque de marshaling a besoin d’un contexte pour effectuer une conversion de System::String
en 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(-trice)
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
}