Предупреждение компилятора (уровень 3) C4996Compiler Warning (level 3) C4996

В коде используется функция, член класса, переменная или typedef, помеченные как устаревшие.Your code uses a function, class member, variable, or typedef that's marked deprecated. Символы являются устаревшими с помощью __declspec(deprecated) модификатора или атрибута c++ 14 [[deprecated]] .Symbols are deprecated by using a __declspec(deprecated) modifier, or the C++14 [[deprecated]] attribute. Фактическое предупреждающее сообщение C4996 указывается deprecated модификатором или атрибутом объявления.The actual C4996 warning message is specified by the deprecated modifier or attribute of the declaration.

Важно!

Это предупреждение всегда является преднамеренным сообщением от автора файла заголовка, объявляющего символ.This warning is always a deliberate message from the author of the header file that declares the symbol. Не используйте нерекомендуемый символ, не зная последствий.Don't use the deprecated symbol without understanding the consequences.

RemarksRemarks

Многие функции, функции элементов, функции шаблонов и глобальные переменные в библиотеках Visual Studio являются устаревшими.Many functions, member functions, template functions, and global variables in Visual Studio libraries are deprecated. Некоторые, такие как функции POSIX и Microsoft, являются устаревшими, так как теперь они имеют другое предпочтительное имя.Some, such as POSIX and Microsoft-specific functions, are deprecated because they now have a different preferred name. Некоторые функции библиотеки времени выполнения C являются устаревшими, так как они являются небезопасными и имеют более безопасный вариант.Some C runtime library functions are deprecated because they're insecure and have a more secure variant. Другие являются устаревшими, так как они устарели.Others are deprecated because they're obsolete. Сообщения об устаревании обычно содержат предлагаемую замену устаревшей функции или глобальной переменной.The deprecation messages usually include a suggested replacement for the deprecated function or global variable.

Отключить предупреждениеTurn off the warning

Чтобы устранить проблему C4996, обычно рекомендуется изменить код.To fix a C4996 issue, we usually recommend you change your code. Вместо этого используйте предложенные функции и глобальные переменные.Use the suggested functions and global variables instead. Если необходимо использовать существующие функции или переменные по соображениям переносимости, можно отключить предупреждение.If you need to use the existing functions or variables for portability reasons, you can turn off the warning.

Отключение предупреждения для определенной строки кодаTurn off the warning for a specific line of code

Чтобы отключить предупреждение для определенной строки кода, используйте warning директиву pragma, #pragma warning(suppress : 4996) .To turn off the warning for a specific line of code, use the warning pragma, #pragma warning(suppress : 4996).

Отключение предупреждения в файлеTurn off the warning within a file

Чтобы отключить предупреждение в файле для всех элементов, которые следуют за ним, используйте прагма-директиву warning, #pragma warning(disable : 4996) .To turn off the warning within a file for everything that follows, use the warning pragma, #pragma warning(disable : 4996).

Отключение предупреждения в сборках из командной строкиTurn off the warning in command-line builds

Чтобы отключить предупреждение глобально в сборках командной строки, используйте /wd4996 параметр командной строки.To turn off the warning globally in command-line builds, use the /wd4996 command-line option.

Отключение предупреждения для проекта в Visual StudioTurn off the warning for a project in Visual Studio

Чтобы отключить предупреждение для всего проекта в интегрированной среде разработки Visual Studio, сделайте следующее:To turn off the warning for an entire project in the Visual Studio IDE:

  1. Откройте диалоговое окно страницы свойств для проекта.Open the Property Pages dialog for your project. Сведения об использовании диалогового окна страницы свойств см. в разделе страницы свойств.For information on how to use the Property Pages dialog, see Property Pages.

  2. Выберите страницу свойств свойства конфигурации > C/C++ > Дополнительно .Select the Configuration Properties > C/C++ > Advanced property page.

  3. Измените свойство Отключить определенные предупреждения , чтобы добавить 4996 .Edit the Disable Specific Warnings property to add 4996. Нажмите кнопку ОК , чтобы применить изменения.Choose OK to apply your changes.

Отключение предупреждения с помощью макросов препроцессораDisable the warning using preprocessor macros

Вы также можете использовать макросы препроцессора, чтобы отключить некоторые определенные классы предупреждений об устаревании, используемых в библиотеках.You can also use preprocessor macros to turn off certain specific classes of deprecation warnings used in the libraries. Эти макросы описаны ниже.These macros are described below.

Чтобы определить макрос препроцессора в Visual Studio, выполните следующие действия.To define a preprocessor macro in Visual Studio:

  1. Откройте диалоговое окно страницы свойств для проекта.Open the Property Pages dialog for your project. Сведения об использовании диалогового окна страницы свойств см. в разделе страницы свойств.For information on how to use the Property Pages dialog, see Property Pages.

  2. Разверните Свойства конфигурации > препроцессора > C/C++.Expand Configuration Properties > C/C++ > Preprocessor.

  3. В свойстве определения препроцессора добавьте имя макроса.In the Preprocessor Definitions property, add the macro name. Нажмите кнопку ОК для сохранения изменений, а затем выполните повторную сборку проекта.Choose OK to save, and then rebuild your project.

Чтобы определить макрос только в определенных исходных файлах, добавьте строку #define EXAMPLE_MACRO_NAME , например перед любой строкой, содержащей файл заголовка.To define a macro only in specific source files, add a line such as #define EXAMPLE_MACRO_NAME before any line that includes a header file.

Ниже приведены некоторые из распространенных источников предупреждений и ошибок C4996:Here are some of the common sources of C4996 warnings and errors:

Имена функций POSIXPOSIX function names

The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name: new-name. See online help for details.The POSIX name for this item is deprecated. Instead, use the ISO C and C++ conformant name: new-name. See online help for details.

Корпорация Майкрософт переименовала некоторые библиотечные функции POSIX и Microsoft в CRT, чтобы они соответствовали ограничениям C99 и C++ 03 в зарезервированных и глобальных именах, определяемых реализацией.Microsoft renamed some POSIX and Microsoft-specific library functions in the CRT to conform with C99 and C++03 constraints on reserved and global implementation-defined names. Только имена являются устаревшими, а не сами функции.Only the names are deprecated, not the functions themselves. В большинстве случаев в имя функции добавляется символ подчеркивания для создания имени.In most cases, a leading underscore was added to the function name to create a conforming name. Компилятор выдает предупреждение об устаревании для имени исходной функции и предлагает предпочтительное имя.The compiler issues a deprecation warning for the original function name, and suggests the preferred name.

Чтобы устранить эту проблему, обычно рекомендуется изменить код так, чтобы вместо него использовались предлагаемые имена функций.To fix this issue, we usually recommend you change your code to use the suggested function names instead. Однако обновленные имена относятся только к Microsoft.However, the updated names are Microsoft-specific. Если необходимо использовать имена существующих функций по соображениям переносимости, можно отключить эти предупреждения.If you need to use the existing function names for portability reasons, you can turn off these warnings. Функции по-прежнему доступны в библиотеке с их исходными именами.The functions are still available in the library under their original names.

Чтобы отключить предупреждения об устаревании для этих функций, определите макрос препроцессора _CRT_NONSTDC_NO_WARNINGS .To turn off deprecation warnings for these functions, define the preprocessor macro _CRT_NONSTDC_NO_WARNINGS. Этот макрос можно определить в командной строке, включив параметр /D_CRT_NONSTDC_NO_WARNINGS .You can define this macro at the command line by including the option /D_CRT_NONSTDC_NO_WARNINGS.

Небезопасные функции библиотеки CRTUnsafe CRT Library functions

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

Корпорация Майкрософт не имеет устаревших функций и глобальных библиотек CRT и C++, так как доступны более безопасные версии.Microsoft deprecated some CRT and C++ Standard Library functions and globals because more secure versions are available. Большинство устаревших функций допускают непроверенный доступ на чтение или запись к буферам.Most of the deprecated functions allow unchecked read or write access to buffers. Их неправильное использование может привести к серьезным проблемам безопасности.Their misuse can lead to serious security issues. Компилятор выдает предупреждение об устаревании для этих функций и предлагает предпочтительную функцию.The compiler issues a deprecation warning for these functions, and suggests the preferred function.

Чтобы устранить эту проблему, рекомендуется вместо этого использовать функцию или переменную safe-version .To fix this issue, we recommend you use the function or variable safe-version instead. Иногда вы не можете обеспечить переносимость или обратную совместимость.Sometimes you can't, for portability or backwards compatibility reasons. Тщательно проверьте, не возможно ли перезапись или Пересчитывание буфера в коде.Carefully verify it's not possible for a buffer overwrite or overread to occur in your code. После этого предупреждение можно отключить.Then, you can turn off the warning.

Чтобы отключить предупреждения об устаревании для этих функций в CRT, определите _CRT_SECURE_NO_WARNINGS .To turn off deprecation warnings for these functions in the CRT, define _CRT_SECURE_NO_WARNINGS.

Чтобы отключить предупреждения о нерекомендуемых глобальных переменных, определите _CRT_SECURE_NO_WARNINGS_GLOBALS .To turn off warnings about deprecated global variables, define _CRT_SECURE_NO_WARNINGS_GLOBALS.

Дополнительные сведения об этих устаревших функциях и глобальных параметрах см. в разделе функции безопасности в библиотеках CRT и безопасные: Стандартная библиотека C++.For more information about these deprecated functions and globals, see Security Features in the CRT and Safe Libraries: C++ Standard Library.

Ненадежные функции стандартной библиотекиUnsafe Standard Library functions

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

В Visual Studio 2015 это предупреждение появляется в отладочных сборках, поскольку некоторые функции шаблона стандартной библиотеки C++ не проверяют правильность параметров.In Visual Studio 2015, this warning appears in debug builds because certain C++ Standard Library template functions don't check parameters for correctness. Часто это обусловлено тем, что функции не хватает информации для проверки границ контейнера.Often it's because not enough information is available to the function to check container bounds. Или, так как итераторы могут неправильно использоваться функцией.Or, because iterators may be used incorrectly with the function. Это предупреждение помогает понять эти функции, так как они могут быть источником серьезных брешей в системе безопасности в программе.This warning helps you identify these functions, because they may be a source of serious security holes in your program. Дополнительные сведения см. в разделе проверенные итераторы.For more information, see Checked iterators.

Например, это предупреждение отображается в режиме отладки std::copy , если вместо простого массива передается указатель на элемент.For example, this warning appears in Debug mode if you pass an element pointer to std::copy, instead of a plain array. Чтобы устранить эту проблему, используйте соответствующий объявленный массив, чтобы библиотека могла проверять экстенты массива и проверять границы.To fix this issue, use an appropriately declared array, so the library can check the array extents and do bounds checking.

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

Несколько стандартных алгоритмов библиотеки были обновлены в версии C++ 14 с двумя диапазонами.Several standard library algorithms were updated to have "dual range" versions in C++14. При использовании двух версий диапазона второй диапазон предоставляет необходимые проверки границ:If you use the dual range versions, the second range provides the necessary bounds checking:

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

В этом примере показано несколько способов использования стандартной библиотеки для проверки использования итератора, и если непроверенное использование может быть опасным:This example demonstrates several more ways the standard library may be used to check iterator usage, and when unchecked usage may be dangerous:

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

Если вы проверили, что в коде не может быть ошибки переполнения буфера, это предупреждение можно отключить.If you've verified that your code can't have a buffer-overrun error, you can turn off this warning. Чтобы отключить предупреждения для этих функций, определите _SCL_SECURE_NO_WARNINGS .To turn off warnings for these functions, define _SCL_SECURE_NO_WARNINGS.

Проверенные итераторы включеныChecked iterators enabled

Предупреждение C4996 также может возникать, если не используется проверяемый итератор, если _ITERATOR_DEBUG_LEVEL определен как 1 или 2.C4996 can also occur if you don't use a checked iterator when _ITERATOR_DEBUG_LEVEL is defined as 1 or 2. По умолчанию для сборок в режиме отладки установлено значение 2, а для розничных сборок — 0.It's set to 2 by default for debug mode builds, and to 0 for retail builds. Дополнительные сведения см. в разделе проверенные итераторы.For more information, see Checked iterators.

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

Ненадежный код MFC или ATLUnsafe MFC or ATL code

Предупреждение C4996 может возникать при использовании функций MFC или ATL, которые являются устаревшими по соображениям безопасности.C4996 can occur if you use MFC or ATL functions that were deprecated for security reasons.

Чтобы устранить эту проблему, настоятельно рекомендуется изменить код, чтобы вместо этого использовать обновленные функции.To fix this issue, we strongly recommend you change your code to use updated functions instead.

Сведения о подавлении этих предупреждений см. в разделе _AFX_SECURE_NO_WARNINGS .For information on how to suppress these warnings, see _AFX_SECURE_NO_WARNINGS.

Устаревшие функции и переменные CRTObsolete CRT functions and variables

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

Некоторые функции и глобальные переменные библиотеки устарели.Some library functions and global variables are deprecated as obsolete. Эти функции и переменные могут быть удалены в будущей версии библиотеки.These functions and variables may be removed in a future version of the library. Компилятор выдает предупреждение об устаревании для этих элементов и предлагает предпочтительную альтернативу.The compiler issues a deprecation warning for these items, and suggests the preferred alternative.

Чтобы устранить эту проблему, мы рекомендуем изменить код для использования предлагаемой функции или переменной.To fix this issue, we recommend you change your code to use the suggested function or variable.

Чтобы отключить предупреждения об устаревании для этих элементов, определите _CRT_OBSOLETE_NO_WARNINGS .To turn off deprecation warnings for these items, define _CRT_OBSOLETE_NO_WARNINGS. Дополнительные сведения см. в документации по устаревшей функции или переменной.For more information, see the documentation for the deprecated function or variable.

Ошибки маршалирования в коде CLRMarshaling errors in CLR code

Предупреждение C4996 также может возникать при использовании библиотеки маршалирования CLR.C4996 can also occur when you use the CLR marshaling library. В этом случае C4996 является ошибкой, а не предупреждением.In this case, C4996 is an error, not a warning. Эта ошибка возникает при использовании marshal_as для преобразования между двумя типами данных, для которых требуется marshal_context класс.The error occurs when you use marshal_as to convert between two data types that require a marshal_context Class. Эту ошибку также можно получить, когда библиотека упаковки не поддерживает преобразование.You can also receive this error when the marshaling library doesn't support a conversion. Дополнительные сведения о библиотеке упаковки см. в разделе Общие сведения о маршалировании в C++.For more information about the marshaling library, see Overview of marshaling in C++.

Этот пример приводит к возникновению предупреждения C4996, поскольку библиотеке маршалирования требуется контекст для преобразования из в System::String const char * .This example generates C4996 because the marshaling library requires a context to convert from a System::String to a 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;
}

Пример: определяемая пользователем устаревшая функцияExample: User-defined deprecated function

Атрибут можно использовать deprecated в собственном коде для предупреждения вызывающих объектов, когда больше не рекомендуется использовать определенные функции.You can use the deprecated attribute in your own code to warn callers when you no longer recommend use of certain functions. В этом примере C4996 создается в двух местах: по одному для строки, для которой объявлена устаревшая функция, а другая — для строки, в которой используется функция.In this example, C4996 is generated in two places: One for the line the deprecated function is declared on, and one for the line where the function is used.

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