Ошибка c4996 visual studio

Обновлено: 05.07.2024

Используя последнюю фиксацию, ошибки и предупреждения C4996 появляются при каждом вызове функции манипулирования строкой:

  • std::strcpy (Предупреждение)
  • std::strcat (Предупреждение)
  • std::copy (Ошибка - сбой компиляции) в месте назначения без итератора / указателя

изменение std::copy(m_start, m_end, buf.data()); на std::copy(m_start, m_end, buf.begin()); устраняет эту проблему.

Все 8 Комментарий

Поскольку здесь мы имеем дело со строкой, на мой взгляд, подход std::string с резервированием N байтов является лучшим выбором. Вам не нужно будет вызывать strcat / strcpy или делать это вручную, так как мы получили + operator и = operator . Указанный вами strlen не затронут и по-прежнему может использоваться, но рекомендуется переключиться на .length() .

Есть только одно использование strlen для данных массива, которые я нашел в последней фиксации

который затем можно заменить на .cbegin() , .cend() .

Причина использования std::array<char, N> вместо std::string в этом контексте заключалась в том, чтобы избежать выделения кучи, что является узким местом производительности.

Ну и std::string и std::vector выполняют распределение кучи. Так что для критической производительности я думаю, что игнорирование предупреждения того стоит, поскольку мы контролируем входные данные «.», «-0.0» и «0.0».

Другое решение для предупреждений

Тогда звоните вот так JSON_STRCAT(JSON_STROUT(m_buf.data(), m_buf.size()), ".0");

Я провел некоторый рефакторинг, чтобы избежать небезопасных вызовов, см. 83a9c60dbda7ab81a34f38cce037440316311eac. Я объединил вызов strlen и std::none_of в один цикл for и развернул stdcpy / strcat в последовательность назначений. Что вы думаете?

@prsyahmi Не могли бы вы попробовать самую последнюю версию?

Код выглядит хорошо, и здесь он отлично компилируется, больше никаких предупреждений и ошибок 👍 Думаю, теперь это можно закрыть. Спасибо!

Visual Studio unsafe error скриншот

Компилятор в Visual Studio сильно отличается от привычных большинству программистов GCC или CLANG, из-за чего при написании кода на C или C++ очень часто возникают неожиданные проблемы в виде ошибки использования стандартных функций, например, scanf, fopen, sscanf и тому подобным. Студия предлагает заменять функции на безопасные (повезёт, если нужно просто добавить _s к функции с ошибкой, но нередко в этих функциях идёт иной набор аргументов, нежели в обычной программе). Если вы не готовы с этим мириться, то этот пост для вас!

Давайте для начала создадим обычный консольный проект в Visual Studio и напишем простенькую программу, которая запрашивает ввод двух чисел, вводит их и затем выводит на экран.

Попробовав выполнить сборку проекта, обнаружим те самые ошибки.

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

1. Выберем пункт "Проект" в верхнем меню

2. В открывшемся списке щёлкнем по "Свойства название_проекта"

Программа, вводящая два числа и выводящая их

Ошибка компиляции из-за небезопасности функций


3. В появившемся окне выберем Свойства конфигурации , C/C++ , Препроцессор

4. В строке Определения препроцессора допишем в самый конец строку ;_CRT_SECURE_NO_WARNINGS

Свойства конфигурации

Определения препроцессора

OK

6. Попробуем заново выполнить сборку проекта:

Успешная сборка проекта

Ошибки исчезли, сборка прошла успешно и программа прекрасно работает! Теперь можно писать код как обычно, не переживая о необычном поведении Visual Studio!

Фото Перминова Андрея, автора этой статьи

Выпускник МГУ им. М.В. Ломоносова

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

В предыдущих версиях Visual Studio использование таких функций, как _sleep или strncpy, просто выводило предупреждение. В последней версии вдруг вылетела ошибка:

unexpected error

ошибка C4996: '_sleep': эта функция или переменная была заменена более новой библиотекой или функциональностью операционной системы. Вместо этого рассмотрите возможность использования сна. Смотрите справку для деталей.

Прежде чем вы спросите, параметр «Обрабатывать предупреждения как ошибки» отключен, и он выдает ошибку, даже если я отключу все предупреждения!

Очевидно, новые проекты теперь по умолчанию включают «проверку SDK», которая рассматривает эти предупреждения как ошибки. Чтобы отключить его, перейдите в свойства проекта -> Свойства конфигурации -> C / C ++ -> Общие -> Проверки SDL -> Нет.

Чтобы добавить к этому, _CRT_NONSTDC_NO_DEPRECATE работал у меня в VS2019. Одно только _CRT_SECURE_NO_WARNINGS не прояснило это для меня (я определил оба).

Подобно другим ответам, это можно добавить, щелкнув правой кнопкой мыши проект в обозревателе решений, затем перейдя в Свойства-> Свойства конфигурации-> C / C ++ -> Препроцессор-> Определения препроцессора-> Изменить . затем добавив строку _CRT_NONSTDC_NO_DEPRECATE .

Компиляция всех источников, на которые я ссылался:

Судя по всему, жизненный цикл разработки безопасности (SDL) рекомендовал проверки, которые включают включение дополнительных функций генерации безопасного кода и дополнительные предупреждения, связанные с безопасностью, в качестве ошибок.

Шаги для решения этой проблемы:

Проект -> свойства имя_проекта -> Свойства конфигурации -> C / C ++ -> Препроцессор -> Определения препроцессора -> Изменить . добавить строку _CRT_SECURE_NO_WARNINGS

Вы также можете отключить определенные номера предупреждений в C / C ++> Дополнительно> Отключить определенные предупреждения.

Я получаю это предупреждение, но все функции работают нормально.

Эта функция (strcpy) считается небезопасной из-за того, что проверка границ отсутствует и может привести к переполнению буфера. (На самом деле strcpy является позорным для переполнения эксплойтов, и все программисты его избегают - или, по крайней мере, должны его избегать). Совет должен использовать безопасную функцию, которая учитывает размер буфера назначения, чтобы избежать переполнения. Вы также можете использовать strncpy (НО с осторожностью!). Нет проблем с вашим кодом, т.е. Функции будут запускаться, как вы говорите, но попробуйте указать в качестве входного буфера, который больше, чем буфер назначения. Функция переполнит буфер назначения. Проверьте это также текст ссылки

В то время как strcpy является общей строковой функцией, у нее есть история, которая является источником многих ошибок и явлений безопасности в программном обеспечении (из-за простоты переполнения буфера).

Microsoft, стремясь продвигать безопасное кодирование на C и С++, предоставила набор функций замены для опасных строковых методов. Как правило, у них есть оригинальное имя, перенесенное с помощью _s. Следовательно, защищенная версия strcpy от Microsoft - strcpy_s, как рекомендовано в предупреждении. Обратите внимание на эту особенность Microsoft, она не вездесущая.

У вас есть несколько вариантов.

    DEFINE _CRT_SECURE_NO_WARNINGS, если вы не хотите заботиться об этом, оставляя возможность проблем с безопасностью в вашем программном обеспечении.
    Замените свои строковые функции на безопасные, оставляя программное обеспечение менее портативным как следствие
    Оберните защищенные строковые функции и повсеместно используйте обертки, обеспечивая повышенную безопасность на платформах Windows и возвращайтесь к традиционным версиям на других платформах. Функции обертки могут выполняться с помощью MACRO или скомпилированных функций.

Поскольку вы программируете С++, правильным решением является запрет строк char* C-style из вашего кода, где это возможно, и заменить их на std::string (или другой подходящий тип строки).

Не используйте такие функции, как strcpy или strcpy_s или strncpy . Используйте конструктор копирования или оператор присваивания класса string . Или, если вам действительно нужно копировать буферы, используйте std::copy .

Так как VС++ 8 strcpy() и огромный набор других функций считаются небезопасными, поскольку они не имеют проверки границ и могут приводят к переполнению буфера при неправильном использовании.

У вас есть два варианта:

    если вы не уверены - сделайте то, что говорит VС++, и используйте "безопасные" функции. Они вызовут обработчик ошибок, который завершит вашу программу, если что-то пойдет не так.
    Если вы знаете, что делаете, вы знаете, что никакого переполнения никогда не произойдет, и все краевые случаи обрабатываются вашим кодом - определите _CRT_SECURE_NO_WARNINGS до включения заголовков CRT, и это заставит предупреждение уйти.

Существует актуальный способ избежать этого предупреждения, по-прежнему использовать strcpy и быть в безопасности:

Вы можете включить безопасные перегрузки шаблонов. Они будут (если возможно) вывести длины буферов, используемых для их захвата с помощью шаблонных перегрузок. Для меня загадка, почему это не включено по умолчанию в Visual С++.

Это предупреждение в основном информирует вас о том, что strcpy устарел, поскольку копирование строки до \0 может легко привести к неприятным проблемам (переполнение буфера). Причина, по которой strcpy все еще существует и работает, заключается в том, что она является частью стандартного наследия библиотеки, но вам действительно стоит использовать функции str * _s или strn * (которые не только полагаются на поиск завершающего \0 ).

Так как переполнения буфера связаны не только с проблемами безопасности, но и с ошибками, которые относительно сложно отслеживать и исправлять, используя простые функции ванильной строки *, не только нахмуриться, но и может привести к тому, что люди откажутся от вашего кода как неотъемлемо небезопасный.

Читайте также: