Compilerwarnung (Ebene 3) C4996

Ihr Code verwendet eine Funktion, ein Klassenelement, eine Variable oder einen Typdef, der als veraltet gekennzeichnet ist. Symbole sind mit einem __declspec(deprecated) Modifizierer oder dem C++14-Attribut [[deprecated]] veraltet. Die tatsächliche C4996-Warnmeldung wird durch den deprecated Modifizierer oder Attribut der Deklaration angegeben.

Wichtig

Diese Warnung ist immer eine absichtliche Nachricht vom Autor der Kopfzeilendatei, die das Symbol deklariert. Verwenden Sie das veraltete Symbol nicht, ohne die Folgen zu verstehen.

Hinweise

Viele Funktionen, Memberfunktionen, Funktionsvorlagen und globale Variablen in Visual Studio-Bibliotheken sind veraltet. Einige, z. B. POSIX- und Microsoft-spezifische Funktionen, sind veraltet, da sie jetzt einen anderen bevorzugten Namen haben. Einige C-Laufzeitbibliotheksfunktionen sind veraltet, da sie unsicher sind und eine sicherere Variante haben. Andere sind veraltet, weil sie veraltet sind. Die Veralteten Nachrichten enthalten in der Regel einen vorgeschlagenen Ersatz für die veraltete Funktion oder globale Variable.

Die /sdl Compileroption (Zusätzliche Sicherheitsüberprüfungen aktivieren) erhöht diese Warnung auf einen Fehler.

Deaktivieren der Warnung

Um ein C4996-Problem zu beheben, empfehlen wir in der Regel, Ihren Code zu ändern. Verwenden Sie stattdessen die vorgeschlagenen Funktionen und globalen Variablen. Wenn Sie die vorhandenen Funktionen oder Variablen aus Portabilitätsgründen verwenden müssen, können Sie die Warnung deaktivieren.

Deaktivieren der Warnung für eine bestimmte Codezeile

Um die Warnung für eine bestimmte Codezeile zu deaktivieren, verwenden Sie das warning Pragma. #pragma warning(suppress : 4996)

Deaktivieren der Warnung in einer Datei

Wenn Sie die Warnung in einer Datei für alle folgenden Aktionen deaktivieren möchten, verwenden Sie das Pragma der Warnung. #pragma warning(disable : 4996)

Deaktivieren der Warnung in Befehlszeilenbuilds

Verwenden Sie die /wd4996 Befehlszeilenoption, um die Warnung global in Befehlszeilenbuilds zu deaktivieren.

Deaktivieren der Warnung für ein Projekt in Visual Studio

So deaktivieren Sie die Warnung für ein gesamtes Projekt in der Visual Studio-IDE:

  1. Öffnen Sie das Dialogfeld "Eigenschaftenseiten " für Ihr Projekt. Informationen zur Verwendung des Dialogfelds "Eigenschaftenseiten" finden Sie unter "Eigenschaftenseiten".

  2. Wählen Sie die Seite "Konfigurationseigenschaften>C/C++>Advanced" aus.

  3. Bearbeiten Sie die Eigenschaft "Bestimmte Warnungen deaktivieren", um sie hinzuzufügen 4996. Wählen Sie "OK" aus, um Ihre Änderungen anzuwenden.

Deaktivieren der Warnung mithilfe von Präprozessormakros

Sie können auch Präprozessormakros verwenden, um bestimmte Klassen von Veraltetwarnungen zu deaktivieren, die in den Bibliotheken verwendet werden. Diese Makros werden unten beschrieben.

So definieren Sie ein Präprozessormakro in Visual Studio:

  1. Öffnen Sie das Dialogfeld "Eigenschaftenseiten " für Ihr Projekt. Informationen zur Verwendung des Dialogfelds "Eigenschaftenseiten" finden Sie unter "Eigenschaftenseiten".

  2. Erweitern Sie die Konfigurationseigenschaften > C/C++ > -Präprozessor.

  3. Fügen Sie in der Präprozessordefinitionseigenschaft den Makronamen hinzu. Wählen Sie OK aus, um Ihre Änderung zu speichern, und erstellen Sie das Projekt anschließend neu.

Wenn Sie ein Makro nur in bestimmten Quelldateien definieren möchten, fügen Sie eine Zeile wie #define EXAMPLE_MACRO_NAME vor einer Zeile hinzu, die eine Headerdatei enthält.

Hier sind einige der gängigen Quellen von C4996-Warnungen und -Fehlern:

POSIX-Funktionsnamen

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 hat einige POSIX- und Microsoft-spezifische Bibliotheksfunktionen im CRT umbenannt, um den Einschränkungen von C99 und C++03 für reservierte und globale implementierungsdefinierte Namen zu entsprechen. Nur die Namen sind veraltet, nicht die Funktionen selbst. In den meisten Fällen wurde dem Funktionsnamen ein führender Unterstrich hinzugefügt, um einen konformen Namen zu erstellen. Der Compiler gibt eine Veraltetkeitswarnung für den ursprünglichen Funktionsnamen aus und schlägt den bevorzugten Namen vor.

Um dieses Problem zu beheben, empfehlen wir in der Regel, Ihren Code so zu ändern, dass stattdessen die vorgeschlagenen Funktionsnamen verwendet werden. Die aktualisierten Namen sind jedoch Microsoft-spezifisch. Wenn Sie die vorhandenen Funktionsnamen aus Portabilitätsgründen verwenden müssen, können Sie diese Warnungen deaktivieren. Die Funktionen sind weiterhin in der Bibliothek unter ihren ursprünglichen Namen verfügbar.

Definieren Sie das Präprozessormakro _CRT_NONSTDC_NO_WARNINGS, um die Veraltetkeitswarnungen für diese Funktionen zu deaktivieren. Sie können dieses Makro in der Befehlszeile definieren, indem Sie die Option /D_CRT_NONSTDC_NO_WARNINGSeinschließen.

Unsichere CRT-Bibliotheksfunktionen

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 hat einige CRT- und C++-Standardbibliotheksfunktionen und -globalen veraltet, da sicherere Versionen verfügbar sind. Die meisten veralteten Funktionen ermöglichen deaktivierten Lese- oder Schreibzugriff auf Puffer. Ihr Missbrauch kann zu schwerwiegenden Sicherheitsproblemen führen. Der Compiler gibt für diese Funktionen eine Veraltungswarnung aus und schlägt die bevorzugte Funktion vor.

Um dieses Problem zu beheben, empfiehlt es sich, stattdessen die Funktion oder Variable safe-version zu verwenden. Manchmal können Sie aus Gründen der Portabilität oder abwärtskompatibilität nicht. Überprüfen Sie sorgfältig, ob ein Puffer im Code überschrieben oder übergelesen werden kann. Anschließend können Sie die Warnung deaktivieren.

Zum Deaktivieren von Veraltetkeitswarnungen für diese Funktionen im CRT definieren _CRT_SECURE_NO_WARNINGSSie .

Um Warnungen zu veralteten globalen Variablen zu deaktivieren, definieren Sie _CRT_SECURE_NO_WARNINGS_GLOBALS.

Weitere Informationen zu diesen veralteten Funktionen und Globalen finden Sie unter "Sicherheitsfeatures" in der CRT- und Tresor-Bibliotheken: C++-Standardbibliothek.

Unsichere Standardbibliotheksfunktionen

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

In Visual Studio 2015 wird diese Warnung in Debugbuilds angezeigt, da bestimmte C++-Standardbibliotheksfunktionsvorlagen keine Parameter auf Korrektheit überprüfen. Häufig liegt es daran, dass nicht genügend Informationen für die Funktion verfügbar sind, um Containergrenzen zu überprüfen. Oder weil Iteratoren möglicherweise falsch mit der Funktion verwendet werden. Diese Warnung hilft Ihnen, diese Funktionen zu identifizieren, da sie möglicherweise eine Quelle schwerwiegender Sicherheitslöcher in Ihrem Programm sind. Weitere Informationen finden Sie unter "Überprüfte Iteratoren".

Diese Warnung wird beispielsweise im Debugmodus angezeigt, wenn Sie einen Elementzeiger std::copyanstelle eines einfachen Arrays übergeben. Um dieses Problem zu beheben, verwenden Sie ein entsprechend deklariertes Array, sodass die Bibliothek die Arrayausdehnungen überprüfen und Begrenzungen überprüfen kann.

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

Mehrere Standardbibliotheksalgorithmen wurden aktualisiert, um "duale Bereichsversionen" in C++14 zu verwenden. Wenn Sie die Versionen des dualen Bereichs verwenden, stellt der zweite Bereich die erforderliche Begrenzungsprüfung bereit:

// 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;
}

In diesem Beispiel werden mehrere weitere Möglichkeiten veranschaulicht, wie die Standardbibliothek verwendet werden kann, um die Iteratorverwendung zu überprüfen, und wenn die deaktivierte Verwendung gefährlich sein kann:

// 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);
}

Wenn Sie überprüft haben, dass ihr Code keinen Pufferüberlauffehler haben kann, können Sie diese Warnung deaktivieren. Um Warnungen für diese Funktionen zu deaktivieren, definieren Sie _SCL_SECURE_NO_WARNINGS.

Aktivierte Iteratoren

C4996 kann auch auftreten, wenn Sie keinen aktivierten Iterator verwenden, wenn _ITERATOR_DEBUG_LEVEL sie als 1 oder 2 definiert ist. Sie ist standardmäßig auf 2 für Debugmodusbuilds und auf 0 für Einzelhandelsbuilds festgelegt. Weitere Informationen finden Sie unter "Überprüfte Iteratoren".

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

Unsicherer MFC- oder ATL-Code

C4996 kann auftreten, wenn Sie MFC- oder ATL-Funktionen verwenden, die aus Sicherheitsgründen veraltet waren.

Um dieses Problem zu beheben, empfehlen wir dringend, den Code so zu ändern, dass stattdessen aktualisierte Funktionen verwendet werden.

Informationen zum Unterdrücken dieser Warnungen finden Sie unter _AFX_SECURE_NO_WARNINGS.

Veraltete CRT-Funktionen und -Variablen

This function or variable has been superseded by newer library or operating system functionality. Consider using new_item instead. See online help for details.

Einige Bibliotheksfunktionen und globale Variablen wurden als veraltet gekennzeichnet. Diese Funktionen und Variablen werden möglicherweise in einer zukünftigen Version der Bibliothek entfernt. Der Compiler gibt für diese Elemente eine Veraltungswarnung aus und schlägt die bevorzugte Alternative vor.

Um dieses Problem zu beheben, empfehlen wir, den Code so zu ändern, dass die vorgeschlagene Funktion oder Variable verwendet wird.

Zum Deaktivieren von Warnhinweisen für diese Elemente definieren Sie _CRT_OBSOLETE_NO_WARNINGS. Weitere Informationen finden Sie in der Dokumentation für die veraltete Funktion oder Variable.

Marshaling-Fehler im CLR-Code

C4996 kann auch auftreten, wenn Sie die CLR-Marshallingbibliothek verwenden. In diesem Fall ist C4996 ein Fehler, keine Warnung. Der Fehler tritt auf, wenn Sie zum Konvertieren zwischen zwei Datentypen verwenden marshal_as , die eine marshal_context Klasse erfordern. Sie können diesen Fehler auch erhalten, wenn die Marshaling-Bibliothek keine Konvertierung unterstützt. Weitere Informationen zur Marshaling-Bibliothek finden Sie unter Übersicht über das Marshalling in C++.

In diesem Beispiel wird C4996 generiert, da für die Marshaling-Bibliothek ein Kontext zum Konvertieren von einem System::String in ein 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;
}

Beispiel: Benutzerdefinierte veraltete Funktion

Sie können das deprecated Attribut in Ihrem eigenen Code verwenden, um Aufrufer zu warnen, wenn Sie bestimmte Funktionen nicht mehr empfehlen. In diesem Beispiel wird C4996 an zwei Stellen generiert: Eine für die Zeile, für die die Funktion veraltet ist, wird deklariert und eine für die Zeile, in der die Funktion verwendet wird.

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