Compartir a través de


Advertencia del compilador (nivel 3) C4996

'función': el símbolo se ha declarado obsoleto también 'std::<nombre de función>': llamada de función con parámetros que pueden no ser seguros; esta llamada depende del llamador para comprobar que los valores pasados son correctos.Para deshabilitar esta advertencia, utilice -D_SCL_SECURE_NO_WARNINGS.Consulte en la documentación cómo se usan los 'iteradores comprobados' de Visual C++.

Esta advertencia o error tiene muchos significados posibles.

C4996 puede ocurrir porque el compilador encontró una función marcada como deprecated. Puede que la función deje de ser compatible en futuras versiones. Se puede evitar esta advertencia mediante pragma warning (ver ejemplo a continuación).

Algunas funciones de la biblioteca estándar de C++ y CRT han quedado obsoletas en beneficio de funciones nuevas más seguras. Para obtener más información sobre las funciones que se usan en su lugar, consulte la documentación de la función deprecated en el mensaje de error. Para desactivar las advertencias de degradación de CRT, defina _CRT_SECURE_NO_WARNINGS. Para obtener más información acerca de las funciones obsoletas, vea Características de seguridad de CRT y Bibliotecas seguras: Biblioteca estándar de C++.

La advertencia C4996 aparecerá si se usan miembros de los archivos de encabezado <hash_map> y <hash_set> en el espacio de nombres std. Vea El espacio de nombres stdext para obtener más información.

La advertencia C4996 también puede producirse si se utilizan funciones MFC o ATL que quedaron desusadas por razones de seguridad. Para suprimir estas advertencias, vea _AFX_SECURE_NO_WARNINGS y _ATL_SECURE_NO_WARNINGS.

La advertencia C4996 puede aparecer también cuando se utiliza la biblioteca de cálculo de referencias. En este caso, C4996 es un error y no una advertencia. Este error se producirá al utilizar marshal_as para convertir entre dos tipos de datos que requieren una marshal_context (Clase). También recibirá este error cuando la biblioteca de cálculo de referencias no admita una conversión. Para obtener más información sobre la biblioteca de cálculo de referencias, vea Información general del cálculo de referencias en C++.

En el primer ejemplo, la advertencia C4996 se genera para la línea en la que se declara la función y la línea en la que se utiliza la función.

Ejemplo

El ejemplo siguiente genera el error 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);
}

La advertencia C4996 también puede producirse si no se utiliza un iterador comprobado al realizar la compilación con un valor de _ITERATOR_DEBUG_LEVEL definido (establecido en 1 de forma predeterminada para las compilaciones de modo de depuración). Vea Iteradores activados para obtener más información.

En el siguiente ejemplo de código de STL se genera la advertencia 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
}

En el siguiente ejemplo de código de STL se genera C4996 como una advertencia: Los comentarios están alineados.

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

En el ejemplo siguiente se genera la advertencia C4996 porque la biblioteca de cálculo de referencias exige un contexto para convertir un objeto System::String en 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;
}