Share via


Avertissement du compilateur (niveau 3) C4996

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.

Notes

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 :

  1. Ouvrez la boîte de dialogue Pages de propriétés de votre 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.

  2. Sélectionnez la page propriétés>de configuration C/C++>Propriétés avancées.

  3. Modifiez la propriété Disable Specific Warnings 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 :

  1. Ouvrez la boîte de dialogue Pages de propriétés de votre 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.

  2. Développez le préprocesseur C/C++ > des propriétés > de configuration.

  3. Dans la propriété Preprocessor Definitions , 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 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

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, 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

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 supprimé aux mémoires tampons case activée. 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 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 Coffre : 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++ n’case activée pas de paramètres pour l’exactitude. Souvent, c’est parce que les informations insuffisantes sont disponibles pour la fonction pour case activée limites de 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 correctement déclaré, afin que la bibliothèque puisse case activée les étendues du tableau et effectuer des limites case activée ing.

// 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 à deux plages, la deuxième plage fournit les limites nécessaires case activée ing :

// 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 case activée l’utilisation de l’itérateur, et lorsque l’utilisation non case activé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 case activée lorsqu’il _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 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

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 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 pour 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
}