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

Код использует функцию, член класса, переменную или типдеф, помеченную как нерекомендуемую. Символы помечаются как устаревшие с помощью модификатора __declspec(deprecated) или атрибута C++14 [[deprecated]]. Фактическое предупреждение C4996 задается модификатором или атрибутом объявления deprecated.

Это важно

Это предупреждение всегда является осознанным сообщением автора файла заголовка, объявляющего символ. Не используйте устаревший символ без понимания последствий.

Замечания

Многие функции, функции-члены, шаблоны функций и глобальные переменные в библиотеках Visual Studio устарели. Некоторые функции, такие как функции POSIX и специфичные для Microsoft функции, устарели, так как теперь они имеют другое предпочтительное имя. Некоторые функции библиотеки среды выполнения C устарели, так как они небезопасны и имеют более безопасный вариант. Другие помечены как устаревшие, поскольку они устарели. Сообщения об устаревании обычно включают предлагаемую замену устаревшей функции или глобальной переменной.

Параметр компилятора /sdl (включение дополнительных проверок безопасности) преобразует это предупреждение в ошибку.

Отключите предупреждение

Чтобы устранить проблему C4996, обычно рекомендуется изменить код. Вместо этого используйте предлагаемые функции и глобальные переменные. Если вам нужно использовать существующие функции или переменные по причинам переносимости, вы можете отключить предупреждение.

Отключите предупреждение для определенной строки кода

Чтобы отключить предупреждение для определенной строки кода, используйте warning pragma, #pragma warning(suppress : 4996).

Отключите предупреждение в файле

Чтобы отключить предупреждение в файле для всего следующего, используйте директиву pragma warning, #pragma warning(disable : 4996).

Отключите предупреждение в сборках командной строки

Чтобы отключить предупреждение глобально в сборках командной строки, используйте параметр командной строки /wd4996.

Отключите предупреждение для проекта в Visual Studio

Чтобы отключить предупреждение для всего проекта в интегрированной среде разработки Visual Studio, выполните следующие действия.

  1. Откройте диалоговое окно "Страницы свойств" для проекта. Сведения об использовании диалогового окна "Страницы свойств" см. в разделе "Страницы свойств".
  2. Выберите страницу свойств Конфигурация>C/C++>Дополнительно.
  3. Измените свойство Disable Specific Warnings, чтобы добавить 4996. Выберите ОК, чтобы применить изменения.

Отключите предупреждение с помощью макросов препроцессора

Вы также можете использовать макросы препроцессора для отключения определенных классов предупреждений об устаревании, используемых в библиотеках. Эти макросы описаны ниже.

Чтобы определить макрос препроцессора в Visual Studio, выполните следующее:

  1. Откройте диалоговое окно "Страницы свойств" для проекта. Сведения об использовании диалогового окна "Страницы свойств" см. в разделе "Страницы свойств".
  2. Разверните Свойства конфигурации > C/C++ > Препроцессор.
  3. В свойстве "Определения препроцессора" добавьте имя макроса. Нажмите "ОК", чтобы сохранить, а затем перестроить проект.

Чтобы определить макрос только в определенных исходных файлах, добавьте строку, например #define EXAMPLE_MACRO_NAME, перед любой строкой с директивой include для заголовочного файла.

Ниже приведены некоторые распространенные источники предупреждений и ошибок C4996:

Note

В Visual Studio 2017 версии 15.8 были удалены предупреждения C4996, управляемые с помощью _SCL_SECURE_NO_WARNINGS, из стандартной библиотеки Microsoft C++. Текущие версии библиотеки не выдают эти предупреждения. Дополнительные сведения см. в статье STL Features and Fixes in VS 2017 15.8.

Имена функций POSIX

Имя POSIX для этого элемента устарело. Вместо этого используйте имя, соответствующее стандартам ISO C и C++: new-name Дополнительные сведения см. в онлайн-справке.

Корпорация Майкрософт переименовала некоторые библиотечные функции POSIX и специфичные для Microsoft в CRT, чтобы соответствовать ограничениям C99 и C++03 для зарезервированных и глобальных имен, определяемых реализацией. Устарели только имена, а не сами функции. В большинстве случаев к имени функции было добавлено ведущее подчеркивание для создания соответствующего имени. Компилятор выдает предупреждение об устаревании для имени исходной функции и предлагает предпочтительное имя.

Чтобы устранить эту проблему, обычно рекомендуется изменить код, чтобы вместо этого использовать предлагаемые имена функций. Однако обновленные имена специфичны для Microsoft. Если вам нужно использовать существующие имена функций по причинам переносимости, вы можете отключить эти предупреждения. Функции по-прежнему доступны в библиотеке под их исходными именами.

Чтобы отключить предупреждения об устаревании этих функций, определите макрос препроцессора _CRT_NONSTDC_NO_WARNINGS. Этот макрос можно определить в командной строке, включив параметр /D_CRT_NONSTDC_NO_WARNINGS.

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

Эта функция или переменная могут быть небезопасными. Рассмотрите возможность использовать safe-version вместо этого. Чтобы отключить предупреждения об устаревании, используйте _CRT_SECURE_NO_WARNINGS. Дополнительные сведения см. в справке по Интернету.

Корпорация Майкрософт не рекомендует некоторые функции и глобальные переменные стандартной библиотеки CRT и C++, так как доступны более безопасные версии. Большинство устаревших функций позволяют осуществлять непроверенный доступ на чтение или запись к буферам. Их неправильное использование может привести к проблемам безопасности. Компилятор выдает предупреждение об устаревании этих функций и предлагает предпочтительную функцию.

Чтобы устранить эту проблему, рекомендуется вместо этого использовать функцию или переменную safe-version. Иногда вы не можете, по соображениям переносимости или обратной совместимости. Тщательно убедитесь, что в вашем коде не может произойти переполнение буфера или выход за его пределы при чтении. Затем вы можете отключить предупреждение.

Чтобы отключить предупреждения об устаревании этих функций в CRT, определите _CRT_SECURE_NO_WARNINGS.

Чтобы отключить предупреждения о устаревших глобальных переменных, определите _CRT_SECURE_NO_WARNINGS_GLOBALS.

Дополнительные сведения об этих устаревших функциях и глобальных переменных см. в разделе "Функции безопасности" в CRT и безопасных библиотеках: стандартная библиотека C++.

Небезопасные функции стандартной библиотеки

Вызов std:: function_name ::_Unchecked_iterators::_Deprecate для std:: function_name с параметрами, которые могут быть небезопасными, — этот вызов полагается на вызывающую сторону для проверки правильности переданных значений. Чтобы отключить это предупреждение, используйте -D_SCL_SECURE_NO_WARNINGS. Дополнительные сведения об использовании Visual C++ Checked Iterators см. Checked iterators.

Это предупреждение исходит от определенных шаблонов функций стандартной библиотеки C++ при вызове их с итераторами, которые библиотека не может проверить. Часто функция не имеет достаточно сведений, чтобы проверить границы контейнеров, или вы можете неправильно использовать итераторы при работе с этой функцией. Это предупреждение помогает выявить вызовы, которые могут вызвать проблемы с безопасностью в программе. Дополнительные сведения см. в разделе Проверенные итераторы.

Библиотека обрабатывает указатели, которые передаются стандартным алгоритмам, как проверенные итераторы, когда библиотека может определить диапазон назначения. Эта категория предупреждений C4996 сохраняется для случаев, когда библиотека по-прежнему не может выполнить проверку, например для определяемых пользователем итераторов вывода, которые не помечены как проверенные.

Чтобы устранить предупреждение, используйте стандартный итератор, который библиотека уже классифицирует как проверенный, например итератор контейнера, std::back_inserter, или итератор в std::array или std::span. Если вы убедились, что вызов не может выйти за пределы целевого буфера, вы можете отключить это предупреждение, определив _SCL_SECURE_NO_WARNINGS.

Устаревшие функции стандартной библиотеки C++

C4996 также возникает, когда код использует тип стандартной библиотеки, функцию или шаблон, которые объявлены устаревшими стандартом C++. Предупреждение отображается в точке использования, и в сообщении указан устаревший символ.

std::iterator является каноническим примером: стандарт C++17 объявил его устаревшим, и современные режимы соответствия по-прежнему включают его (только не рекомендуется, а не удалено). Другие функции , такие как std::auto_ptr, std::random_shufflestd::unary_functionи std::binary_function - были удалены C++17. В режимах по умолчанию /std:c++17 и в более поздних режимах код, именующий их, не компилируется, а не выдает C4996. Они выдают C4996, только если вы явно снова включите их (например, компилируя с помощью /std:c++14 или определяя макросы, например _HAS_AUTO_PTR_ETC=1 и _HAS_FEATURES_REMOVED_IN_CXX17=1, прежде чем включать стандартные заголовки).

Чтобы исправить предупреждение, замените устаревший символ его современным эквивалентом. Например, вместо выведения типа итератора из std::iterator определите пять псевдонимов типа итератора (iterator_category, pointer, value_type, difference_type и reference) непосредственно в типе итератора:

// C4996_iterator.cpp
// compile with: cl /c /EHsc /W4 /std:c++20 C4996_iterator.cpp
#include <iterator>

// std::iterator was deprecated in C++17, generates C4996
struct my_iterator : std::iterator<std::input_iterator_tag, int>  // C4996
{
    int* p;
    my_iterator(int* p) : p(p) {}
    int& operator*() { return *p; }
    my_iterator& operator++() { ++p; return *this; }
    my_iterator operator++(int) { auto tmp = *this; ++p; return tmp; }
    bool operator==(const my_iterator& o) const { return p == o.p; }
};

// Fix: declare the iterator typedefs directly.
struct my_iterator_fixed
{
    using iterator_category = std::input_iterator_tag;
    using value_type        = int;
    using difference_type   = std::ptrdiff_t;
    using pointer           = int*;
    using reference         = int&;

    int* p;
    my_iterator_fixed(int* p) : p(p) {}
    int& operator*() { return *p; }
    my_iterator_fixed& operator++() { ++p; return *this; }
    my_iterator_fixed operator++(int) { auto tmp = *this; ++p; return tmp; }
    bool operator==(const my_iterator_fixed& o) const { return p == o.p; }
};

Если вы не можете изменить код, вы можете отключить эти предупреждения, определив соответствующий _SILENCE_*_DEPRECATION_WARNING макрос перед включением любого стандартного заголовка. Имя макроса относится к устаревшей функции и включается в предупреждение. Например, _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING для std::iterator. Чтобы отключить все такие предупреждения для заданного стандарта, определите _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS или _SILENCE_ALL_CXX20_DEPRECATION_WARNINGS. Определите эти макросы на уровне проекта (в определениях препроцессора или через /D), так как после обработки стандартного заголовка, включая с помощью предварительно скомпилированного заголовка, более поздний #define в пользовательском коде не влияет на предупреждения, которые он уже выдал.

Небезопасный код MFC или ATL

C4996 может возникать, если вы используете функции MFC или ATL, которые были объявлены устаревшими по соображениям безопасности.

Чтобы устранить эту проблему, настоятельно рекомендуется изменить код для использования обновленных функций.

Сведения о подавлении этих предупреждений см. в разделе _AFX_SECURE_NO_WARNINGS.

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

Эта функция или переменная заменена более новой функциональностью библиотеки или операционной системы. Вместо этого используйте new_item. Дополнительные сведения см. в интерактивной справке.

Некоторые функции библиотеки и глобальные переменные устарели. Эти функции и переменные могут быть удалены в будущей версии библиотеки. Компилятор выдает предупреждение об устаревании для этих элементов и предлагает предпочтительную альтернативу.

Чтобы устранить эту проблему, рекомендуется изменить код, чтобы использовать предлагаемую функцию или переменную.

Чтобы отключить предупреждения об устаревании этих элементов, определите _CRT_OBSOLETE_NO_WARNINGS. Дополнительные сведения см. в документации по устаревшей функции или переменной.

Ошибки маршалинга в коде CLR

C4996 также может возникать при использовании библиотеки маршалинга СРЕДЫ CLR. В этом случае C4996 является ошибкой, а не предупреждением. Ошибка возникает при marshal_as преобразовании между двумя типами данных, для которых требуется marshal_context класс. Эту ошибку также можно получить, если библиотека маршалинга не поддерживает преобразование. Дополнительные сведения о библиотеке маршалинга см. в статье Обзор маршалинга в C++.

В этом примере создается C4996, так как для маршалинговой библиотеки требуется контекст для преобразования из System::String в 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;
}

Пример: определяемая пользователем устаревшая функция

Используйте атрибут [[deprecated]] в собственном коде, чтобы предупредить вызывающий код, если вы больше не рекомендуете использовать определенные функции. Атрибут самого объявления не выдает C4996; только случаи использования нерекомендуемого символа выдают его. В этом примере C4996 создается в месте вызова устаревшей перегрузки.

// 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 func1(int)");
}

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

См. также

__declspec(deprecated)
Безопасные библиотеки: стандартная библиотека C++
Функции безопасности в CRT