Udostępnij za pośrednictwem


Ostrzeżenie kompilatora (poziom 3) C4996

'funkcja': została zadeklarowana jako zaniechana również 'std::<nazwa funkcji>': Wywołanie funkcji z parametrami, które mogą być niebezpieczne — to wywołanie zależy od tego, czy obiekt wywołujący sprawdza poprawność przekazanych wartości.Aby wyłączyć to ostrzeżenie, użyj -D_SCL_SECURE_NO_WARNINGS.Zapoznaj się z dokumentacją na temat używania 'Sprawdzanych iteratorów' języka Visual C++

Ten błąd/ostrzeżenie ma wiele znaczeń.

C4996 może występować, ponieważ kompilator napotkał funkcję oznaczoną jako zaniechana (deprecated).Przyszła wersja prawdopodobnie nie będzie obsługiwała tej funkcji.Można wyłączyć to ostrzeżenie za pomocą dyrektywy ostrzeżenia warning (przykład poniżej).

Niektóre funkcje CRT i standardowej biblioteki języka C++ zostały zaniechane i zastąpione przez nowe, bezpieczniejsze funkcje.Aby uzyskać więcej informacji o tym, której funkcji należy użyć, zajrzyj do dokumentacji zaniechanej funkcji w komunikacie o błędzie.Aby wyłączyć ostrzeżenia o zaniechanych funkcjach CRT, zdefiniuj _CRT_SECURE_NO_WARNINGS.Aby uzyskać więcej informacji na temat zaniechanych funkcji, zobacz Funkcje zabezpieczeń w CRT i Bezpieczne biblioteki: Standardowa biblioteka C++.

Pojawi się C4996, jeśli używasz elementów członkowskich <hash_map> i plików nagłówkowych <hash_set> w przestrzeni nazw std.Zobacz Przestrzeń nazw stdext, aby uzyskać więcej informacji.

C4996 może również wystąpić, jeśli używasz funkcji biblioteki ATL i MFC, które zostały zaniechane ze względów bezpieczeństwa.Aby pominąć te ostrzeżenia, zobacz _AFX_SECURE_NO_WARNINGS i _ATL_SECURE_NO_WARNINGS.

C4996 może również wystąpić, gdy używasz biblioteki dotyczącej organizowania.W tym przypadku C4996 jest błędem, a nie ostrzeżeniem.Ten błąd ma miejsce, gdy korzystasz z marshal_as do konwersji między dwoma typami danych, które wymagają marshal_context — Klasa.Ten błąd wystąpi również, gdy biblioteka dotycząca organizowania nie obsługuje konwersji.Aby uzyskać więcej informacji o bibliotece dotyczącej organizowania, zobacz Omówienie kierowania w języku C++.

W pierwszym przykładzie C4996 jest generowany dla wiersza, w którym zadeklarowano funkcję, i dla wiersza, w którym jest używana funkcja.

Przykład

Poniższy przykład spowoduje wygenerowanie błędu C4996.

// C4996.cpp
// compile with: /W3
// C4996 warning expected
#include <stdio.h>

// #pragma warning(disable : 4996)
void func1(void) {
   printf_s("\nIn func1");
}

__declspec(deprecated) void func1(int) {
   printf_s("\nIn func2");
}

int main() {
   func1();
   func1(1);
}

C4996 może również wystąpić, jeśli nie używasz iteratora sprawdzanego podczas kompilacji ze zdefiniowanym _ITERATOR_DEBUG_LEVEL (dla kompilacji w trybie debugowania domyślnie ustawione na 1). Aby uzyskać więcej informacji, zobacz Zaznaczone iteratory.

W poniższym przykładzie kodu STL jest generowany błąd C4996.

// C4996_b.cpp
// compile with: /EHsc /W3 /c
#define _ITERATOR_DEBUG_LEVEL 1

#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, b);
    copy(a, a + 3, checked_array_iterator<int *>(b, 3));   // OK
}

Poniższy kod przykładowy STL generuje C4996 jako ostrzeżenie.Komentarze są wbudowane.

#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 will trigger 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 will trigger 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 will trigger a debug assertion)
    // NOTE: This applies only when raw arrays are given to STL 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 will trigger 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 will trigger 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
    // (i.e. it performs no checking, so an overrun will trigger 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);
}

Poniższy przykład generuje C4996, ponieważ biblioteka dotycząca organizowania wymaga kontekstu, aby skonwertować z System::String na 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;
}