Advertencia del compilador (nivel 3) C4996

El código usa una función, un miembro de clase, una variable o una definición de tipo que está marcada como en desuso. Los símbolos están en desuso mediante un __declspec(deprecated) modificador o el atributo C++14 [[deprecated]] . El modificador o atributo de la declaración especifica el mensaje de advertencia C4996 deprecated real.

Importante

Esta advertencia siempre es un mensaje intencionado del autor del archivo de encabezado que declara el símbolo. No use el símbolo en desuso sin comprender las consecuencias.

Comentarios

Muchas funciones, funciones miembro, funciones de plantilla y variables globales de Visual Studio bibliotecas están en desuso. Algunas, como POSIX y las funciones específicas de Microsoft, están en desuso porque ahora tienen un nombre preferido diferente. Algunas funciones de biblioteca en tiempo de ejecución de C están en desuso porque no son seguras y tienen una variante más segura. Otros están en desuso porque están obsoletos. Los mensajes de desuso suelen incluir un reemplazo sugerido para la función o variable global en desuso.

Desactivar la advertencia

Para corregir un problema C4996, normalmente se recomienda cambiar el código. En su lugar, use las funciones sugeridas y las variables globales. Si necesita usar las funciones o variables existentes por motivos de portabilidad, puede desactivar la advertencia.

Desactivar la advertencia de una línea de código específica

Para desactivar la advertencia de una línea de código específica, use la warning pragma , #pragma warning(suppress : 4996).

Desactivar la advertencia dentro de un archivo

Para desactivar la advertencia dentro de un archivo para todo lo que sigue, use la pragma de advertencia, #pragma warning(disable : 4996).

Desactivar la advertencia en las compilaciones de línea de comandos

Para desactivar la advertencia globalmente en las compilaciones de línea de comandos, use la opción /wd4996 de línea de comandos .

Desactivar la advertencia de un proyecto en Visual Studio

Para desactivar la advertencia de un proyecto completo en el IDE Visual Studio:

  1. Abra el cuadro de diálogo Páginas de propiedades del proyecto. Para obtener información sobre cómo usar el cuadro de diálogo Páginas de propiedades, vea Páginas de propiedades.

  2. Seleccione la página de propiedades Propiedades de>configuraciónC/C++>Advanced.

  3. Edite la propiedad Deshabilitar advertencias específicas para agregar 4996. Elija Aceptar para aplicar los cambios.

Deshabilitación de la advertencia mediante macros de preprocesador

También puede usar macros de preprocesador para desactivar determinadas clases específicas de advertencias de desuso que se usan en las bibliotecas. Estas macros se describen a continuación.

Para definir una macro de preprocesador en Visual Studio:

  1. Abra el cuadro de diálogo Páginas de propiedades del proyecto. Para obtener información sobre cómo usar el cuadro de diálogo Páginas de propiedades, vea Páginas de propiedades.

  2. Expanda Propiedades de configuración > Preprocesador de C/C > ++.

  3. En la propiedad Definiciones de preprocesador , agregue el nombre de la macro. Seleccione Aceptar para guardar y, luego, vuelva a generar el proyecto.

Para definir una macro solo en archivos de código fuente específicos, agregue una línea como #define EXAMPLE_MACRO_NAME antes de cualquier línea que incluya un archivo de encabezado.

Estos son algunos de los orígenes comunes de advertencias y errores de C4996:

Nombres de función POSIX

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 ha cambiado el nombre de algunas funciones de biblioteca posix y específicas de Microsoft en CRT para que se ajusten a las restricciones C99 y C++03 en nombres reservados y definidos por la implementación global. Solo los nombres están en desuso, no las propias funciones. En la mayoría de los casos, se agregó un carácter de subrayado inicial al nombre de la función para crear un nombre conforme. El compilador emite una advertencia de desuso para el nombre de función original y sugiere el nombre preferido.

Para corregir este problema, normalmente se recomienda cambiar el código para usar los nombres de función sugeridos en su lugar. Sin embargo, los nombres actualizados son específicos de Microsoft. Si necesita usar los nombres de función existentes por motivos de portabilidad, puede desactivar estas advertencias. Las funciones siguen estando disponibles en la biblioteca con sus nombres originales.

Para desactivar las advertencias de desuso para estas funciones, defina la macro de preprocesador _CRT_NONSTDC_NO_WARNINGS. Puede definir esta macro en la línea de comandos incluyendo la opción /D_CRT_NONSTDC_NO_WARNINGS.

Funciones de la biblioteca CRT no seguras

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 ha dejado en desuso algunas funciones y globales de la biblioteca estándar de CRT y C++ porque hay versiones más seguras disponibles. La mayoría de las funciones en desuso permiten el acceso de lectura o escritura no desactivado a los búferes. Su uso incorrecto puede provocar problemas de seguridad graves. El compilador emite una advertencia de desuso para estas funciones y sugiere la función preferida.

Para corregir este problema, se recomienda usar la función o la variable en su safe-version lugar. A veces no se puede, por motivos de portabilidad o compatibilidad con versiones anteriores. Compruebe detenidamente que no es posible que se sobrescriba o se sobrescriba un búfer en el código. A continuación, puede desactivar la advertencia.

Para desactivar las advertencias de desuso para estas funciones en CRT, defina _CRT_SECURE_NO_WARNINGS.

Para desactivar las advertencias sobre variables globales en desuso, defina _CRT_SECURE_NO_WARNINGS_GLOBALS.

Para obtener más información sobre estas funciones y globales en desuso, vea Características de seguridad en CRT y bibliotecas de Caja fuerte: Biblioteca estándar de C++.

Funciones de la biblioteca estándar no seguras

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

En Visual Studio 2015, esta advertencia aparece en las compilaciones de depuración porque ciertas funciones de plantilla de la biblioteca estándar de C++ no comprueban la corrección de los parámetros. A menudo se debe a que no hay suficiente información disponible para la función para comprobar los límites del contenedor. O bien, porque los iteradores se pueden usar incorrectamente con la función . Esta advertencia le ayuda a identificar estas funciones, ya que pueden ser una fuente de graves problemas de seguridad en el programa. Para obtener más información, vea Iteradores comprobados.

Por ejemplo, esta advertencia aparece en modo de depuración si pasa un puntero de elemento std::copya , en lugar de a una matriz sin formato. Para corregir este problema, use una matriz declarada correctamente para que la biblioteca pueda comprobar las extensiones de la matriz y realizar la comprobación de límites.

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

Se actualizaron varios algoritmos de biblioteca estándar para tener versiones de "intervalo dual" en C++14. Si usa las versiones de intervalo dual, el segundo intervalo proporciona la comprobación de los límites necesarios:

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

En este ejemplo se muestran varias maneras más de usar la biblioteca estándar para comprobar el uso del iterador y, cuando el uso no desactivado puede ser peligroso:

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

Si ha comprobado que el código no puede tener un error de saturación del búfer, puede desactivar esta advertencia. Para desactivar las advertencias de estas funciones, defina _SCL_SECURE_NO_WARNINGS.

Iteradores activados habilitados

C4996 también puede producirse si no se usa un iterador _ITERATOR_DEBUG_LEVEL comprobado cuando se define como 1 o 2. Se establece en 2 de forma predeterminada para las compilaciones en modo de depuración y en 0 para las compilaciones comerciales. Para obtener más información, vea Iteradores comprobados.

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

Código MFC o ATL no seguro

Puede producirse el error C4996 si usa funciones MFC o ATL que quedaron en desuso por motivos de seguridad.

Para corregir este problema, se recomienda encarecidamente cambiar el código para usar funciones actualizadas en su lugar.

Para obtener información sobre cómo suprimir estas advertencias, vea _AFX_SECURE_NO_WARNINGS.

Funciones y variables obsoletas de CRT

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

Algunas variables globales y funciones de la biblioteca están en desuso por estar obsoletas. Es posible que estas funciones y variables se quiten en una versión futura de la biblioteca. El compilador emite una advertencia de desuso para estos elementos y sugiere la alternativa preferida.

Para corregir este problema, se recomienda cambiar el código para usar la función o variable sugerida.

Para desactivar las advertencias de desuso para estos elementos, defina _CRT_OBSOLETE_NO_WARNINGS. Para más información, consulte la documentación de la variable o función en desuso.

Serialización de errores en código CLR

C4996 también puede producirse cuando se usa la biblioteca de serialización CLR. En este caso, C4996 es un error, no una advertencia. El error se produce cuando se usa para marshal_as convertir entre dos tipos de datos que requieren una marshal_context clase . También puede recibir este error cuando la biblioteca de serialización no admite una conversión. Para obtener más información sobre la biblioteca de serialización, vea Información general sobre la serialización en C++.

Este ejemplo genera la C4996 porque la biblioteca de serialización requiere un contexto para convertir de a System::Stringconst 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;
}

Ejemplo: Función en desuso definida por el usuario

Puede usar el atributo en deprecated su propio código para advertir a los autores de llamadas cuando ya no se recomienda el uso de determinadas funciones. En este ejemplo, C4996 se genera en dos lugares: uno para la línea en la que se declara la función en desuso y otro para la línea donde se usa la función.

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