Compilerwarnung (Ebene 3) C4996

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

Wichtig

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

Hinweise

Viele Funktionen, Memberfunktionen, Funktionsvorlagen und globale Variablen in den Visual Studio-Bibliotheken sind als veraltet gekennzeichnet. 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 obsolet sind. Die Meldungen zum veralteten Zustand enthalten normalerweise einen Ersatzvorschlag für die veraltete Funktion oder globale Variable.

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

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

Um die Warnung in einer Datei für alle folgenden Elemente zu deaktivieren, verwenden Sie das Warnungspragma #pragma warning(disable : 4996).

Deaktivieren der Warnung in Befehlszeilenbuilds

Um die Warnung in Befehlszeilenbuilds global zu deaktivieren, verwenden Sie die Befehlszeilenoption /wd4996.

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 Eigenschaftenseite Konfigurationseigenschaften>C/C++>Erweitert aus.

  3. Bearbeiten Sie die Eigenschaft Bestimmte Warnungen deaktivieren, um 4996 hinzuzufügen. Klicken Sie auf OK, um die Änderungen zu übernehmen.

Deaktivieren der Warnung mithilfe von Präprozessormakros

Bestimmte Klassen von Veraltungswarnungen, die in den Bibliotheken verwendet werden, können auch mithilfe von Präprozessormakros deaktiviert 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 Konfigurationseigenschaften > C/C++ > Präprozessor.

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

Um dieses Makro nur in bestimmten Quelldateien zu definieren, fügen Sie eine Zeile wie #define EXAMPLE_MACRO_NAME vor jeder Zeile hinzu, die eine Headerdatei einschließt.

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 in 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 für die ursprünglichen Funktionsnamen eine Veraltungswarnung 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.

Um die Veraltungswarnungen für diese Funktionen zu deaktivieren, definieren Sie das Präprozessor-Makro _CRT_NONSTDC_NO_WARNINGS. Sie können dies auch in der Befehlszeile durch Einschließen der Option /D_CRT_NONSTDC_NO_WARNINGS definieren.

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 als veraltet gekennzeichnet, da sicherere Versionen verfügbar sind. Die meisten veralteten Funktionen ermöglichen ungeschützten 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 ist dies aus Gründen der Portabilität oder Abwärtskompatibilität nicht möglich. Stellen Sie sorgfältig sicher, dass ein Pufferoverwrite oder -overread in Ihrem Code nicht möglich ist. Anschließend können Sie die Warnung deaktivieren.

Um die Veraltungswarnungen für diese Funktionen in der CRT zu deaktivieren, definieren Sie _CRT_SECURE_NO_WARNINGS.

Zum Deaktivieren der Warnungen zu veralteten globalen Variablen definieren Sie _CRT_SECURE_NO_WARNINGS_GLOBALS.

Weitere Informationen zu diesen veralteten Funktionen und Globalen finden Sie unter Sicherheitsfeatures in der CRT und Sichere 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++-Funktionsvorlagen der Standardbibliothek Parameter nicht 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. Ein anderer Grund ist, dass 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ücken in Ihrem Programm sind. Weitere Informationen finden Sie unter Überprüfte Iteratoren.

Diese Warnung wird z. B. im Debugmodus angezeigt, wenn Sie einen Elementzeiger auf std::copy statt auf ein einfaches Array übergeben. Um dieses Problem zu beheben, verwenden Sie ein richtig deklariertes Array, sodass die Bibliothek die Arraydimensionen überprüfen und Begrenzungsprüfungen durchführen 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 Versionen mit „dualen Bereichen“ in C++14 zu verwenden. Wenn Sie die Versionen mit dualen Bereichen 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. Außerdem wird erläutert, wann die unüberprüfte 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 die Warnungen für diese Funktionen zu deaktivieren, definieren Sie _SCL_SECURE_NO_WARNINGS.

Überprüfte Iteratoren aktiviert

C4996 kann auch auftreten, wenn Sie keinen geprüften Iterator verwenden, wenn _ITERATOR_DEBUG_LEVEL als 1 oder 2 definiert ist. Der Wert ist standardmäßig auf 2 für Debugmodusbuilds und auf 0 für Retail-Builds 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 auch bei der Verwendung von MFC- oder ATL-Funktionen auftreten, die aus Sicherheitsgründen als veraltet gekennzeichnet wurden.

Um dieses Problem zu beheben, empfehlen wir, Ihren Code so zu ändern, dass stattdessen die aktualisierten 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, Ihren Code so zu ändern, dass die vorgeschlagene Funktion oder Variable verwendet wird.

Um die Veraltungswarnungen für diese Elemente zu deaktivieren, definieren Sie _CRT_OBSOLETE_NO_WARNINGS. Weitere Informationen finden Sie in der Dokumentation für die veraltete Funktion oder Variable.

Marshalling von Fehlern in CLR-Code

C4996 kann auch auftreten, wenn Sie die CLR-Marshallingbibliothek verwenden. In diesem Fall ist C4996 ein Fehler, keine Warnung. Dieser Fehler tritt auf, wenn Sie marshal_as für die Konvertierung zwischen zwei Datentypen verwenden, die eine marshal_context-Klasse benötigen. Der Fehler wird auch angezeigt, wenn die Marshallingbibliothek eine Konvertierung nicht unterstützt. Weitere Informationen über die Marshallingbibliothek finden Sie unter Übersicht über das Marshalling in C++.

Im folgenden Beispiel wird C4996 erzeugt, weil die Marshallingbibliothek einen Kontext benötigt, um von System::String in const char * zu konvertieren.

// 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 Attribut deprecated in Ihrem eigenen Code verwenden, um Aufrufer zu warnen, wenn Sie die Verwendung bestimmter Funktionen nicht mehr empfehlen. In diesem Beispiel wird C4996 an zwei Stellen generiert: Einmal für die Zeile, für die die veraltete Funktion deklariert wird, und einmal 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
}