Partilhar via


Aviso do compilador (nível 3) C4996

'função': foi declarado preterido também 'std::<nome da função>': a chamada de função com parâmetros que podem não ser seguros – essa chamada depende do chamador verificar se os valores passados estão corretos.Para desabilitar esse aviso, use -D_SCL_SECURE_NO_WARNINGS.Consulte a documentação sobre como usar "iteradores verificados" do Visual C++

Esse aviso/erro tem muitos significados possíveis.

O C4996 pode ocorrer porque o compilador encontrou uma função que foi marcada com deprecated. A função pode não ter mais suporte em uma versão futura. Você pode desativar esse aviso com o pragma warning (exemplo abaixo).

Algumas funções das bibliotecas CRT e C++ padrão foram preteridas em favor de funções novas mais seguras. Para obter mais informações sobre que função deve ser usada, consulte a documentação da função preterida na mensagem de erro. Para desativar avisos de funções CRT preteridas, defina _CRT_SECURE_NO_WARNINGS. Para obter mais informações sobre funções preteridas, consulte Recursos de segurança no CRT e Bibliotecas seguras: Biblioteca Padrão C++.

Você verá C4996 se estiver usando membros dos arquivos de cabeçalho <hash_map> e <hash_set> no namespace std. Consulte O namespace stdext para obter mais informações.

O C4996 também poderá ocorrer se você usar funções MFC ou ATL preteridas por razões de segurança. Para suprimir esses avisos, consulte _AFX_SECURE_NO_WARNINGS e _ATL_SECURE_NO_WARNINGS.

O C4996 também pode ocorrer quando você usa a biblioteca de marshaling. Nesse caso, C4996 é um erro, não um aviso. Esse erro ocorrerá quando você usar marshal_as para converter entre dois tipos de dados que exigem Classe marshal_context. Você também receberá esse erro quando a biblioteca de marshaling não oferecer suporte a uma conversão. Para obter mais informações sobre a biblioteca de marshaling, consulte Visão geral de marshaling no C++.

No primeiro exemplo, C4996 é gerado para a linha em que a função é declarada e para a linha em que a função é usada.

Exemplo

O seguinte exemplo gera 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);
}

O C4996 também pode ocorrer se você não usar um iterador verificado durante a compilação com _ITERATOR_DEBUG_LEVEL definido (definido como 1 por padrão para compilações em modo de depuração). Consulte Iteradores Verificados para obter mais informações.

O seguinte exemplo de código STL gera 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
}

O exemplo de código STL a seguir gera C4996 como um aviso. Os comentários são embutidos.

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

O exemplo a seguir gera C4996 porque a biblioteca de marshaling requer um contexto para converter System::String em 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;
}