Вопрос

На Компилятор C++ Visual Studio 2005., я получаю следующее предупреждение, когда мой код использует открыть и такие звонки.

1>foo.cpp(5) : warning C4996: 'fopen' was declared deprecated
1>        c:\program files\microsoft visual studio 8\vc\include\stdio.h(234) : see declaration of 'fopen'
1>        Message: 'This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_DEPRECATE. See online help for details.'

Как мне это предотвратить?

Это было полезно?

Решение

Похоже, что Microsoft объявила устаревшей множество вызовов, использующих буферы для повышения безопасности кода.Однако решения, которые они предоставляют, не являются портативными.В любом случае, если вы не заинтересованы в использовании защищенной версии их вызовов (например, fopen_s), вам необходимо разместить определение _CRT_SECURE_NO_DEPRECATE перед включенными заголовочными файлами.Например:

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

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

Другие советы

Ну, вы могли бы добавить:

#pragma warning (disable : 4996)

прежде чем использовать fopen, рассматривали ли вы возможность использования fopen_s, как предполагает предупреждение?Он возвращает код ошибки, позволяющий проверить результат вызова функции.

Проблема с простым отключением предупреждений об устаревших функциях заключается в том, что Microsoft может удалить рассматриваемую функцию в более поздней версии CRT, нарушив ваш код (как указано ниже в комментариях, в этом случае этого не произойдет с fopen, потому что это часть стандарты C и C++ ISO).

Это просто наглость Microsoft.«Устарело» означает языковую функцию, которая не может быть предоставлена ​​в будущих версиях стандартного языка/стандартных библиотек, как установлено комитетом по стандартам.Это не означает и не должно означать, что «мы в одностороннем порядке не думаем, что вам следует его использовать», независимо от того, насколько обоснован этот совет.

Если ваш код предназначен для другой ОС (например, Mac OS X, Linux), вы можете использовать следующее:

#ifdef _WIN32
#define _CRT_SECURE_NO_DEPRECATE
#endif

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

Я использую VisualStdio 2008.В этом случае я часто устанавливаю Preprocessor Definitions

Меню\Проект\[ProjectName] Свойства...Альт+Ф7

Если щелкнуть это меню или нажать Alt + F7 в окне проекта, вы увидите «Страницы недвижимости» окно.

Затем см. меню слева от окна.

Свойства конфигурации \ C/C++ \ Препроцессор

Затем добавьте _CRT_SECURE_NO_WARNINGS к \ Определения препроцессора.

Если вы хотите, чтобы его использовали на многих платформах, вы можете использовать прокомментированные определения использования, например:

#if defined(_MSC_VER) || defined(WIN32)  || defined(_WIN32) || defined(__WIN32__) \
                        || defined(WIN64)    || defined(_WIN64) || defined(__WIN64__) 

        errno_t err = fopen_s(&stream,name, "w");

#endif

#if defined(unix)        || defined(__unix)      || defined(__unix__) \
                        || defined(linux)       || defined(__linux)     || defined(__linux__) \
                        || defined(sun)         || defined(__sun) \
                        || defined(BSD)         || defined(__OpenBSD__) || defined(__NetBSD__) \
                        || defined(__FreeBSD__) || defined __DragonFly__ \
                        || defined(sgi)         || defined(__sgi) \
                        || defined(__MACOSX__)  || defined(__APPLE__) \
                        || defined(__CYGWIN__) 

        stream = fopen(name, "w");

#endif

Тем, кто использует версию Visual Studio 2017, кажется, что определение препроцессора, необходимое для выполнения небезопасных операций, изменилось.Вместо этого используйте:

#define _CRT_SECURE_NO_WARNINGS

Тогда он скомпилируется.

Многие из безопасных функций Microsoft, включая fopen_s(), являются частью C11, поэтому теперь они должны быть переносимыми.Вы должны понимать, что безопасные функции различаются поведением исключений, а иногда и возвращаемыми значениями.Кроме того, вы должны знать, что, хотя эти функции стандартизированы, это необязательный часть стандарта (Приложение K), которую не реализуют, по крайней мере, glibc (по умолчанию в Linux) и libc FreeBSD.

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

#pragma once
#if !defined(FCN_S_MACROS_H)
   #define   FCN_S_MACROS_H

   #include <cstdio>
   #include <string> // Need this for _stricmp
   using namespace std;

   // _MSC_VER = 1400 is MSVC 2005. _MSC_VER = 1600 (MSVC 2010) was the current
   // value when I wrote (some of) these macros.

   #if (defined(_MSC_VER) && (_MSC_VER >= 1400) )

      inline extern
      FILE*   fcnSMacro_fopen_s(char *fname, char *mode)
      {  FILE *fptr;
         fopen_s(&fptr, fname, mode);
         return fptr;
      }
      #define fopen(fname, mode)            fcnSMacro_fopen_s((fname), (mode))

   #else
      #define fopen_s(fp, fmt, mode)        *(fp)=fopen( (fmt), (mode))

   #endif //_MSC_VER

#endif // FCN_S_MACROS_H

Конечно, этот подход не реализует ожидаемое поведение исключений.

У меня тоже такая же проблема.Когда я пытаюсь добавить библиотеку opencv

#include <opencv\cv.h>

Я получил не предупреждение, а ошибку.

error C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.    c:\program files (x86)\opencv\build\include\opencv2\flann\logger.h  

Как уже упоминалось, я также использовал директивы препроцессора.Но это не решило проблему.

Я решил это, выполнив следующие действия:

  • Перейдите в «Свойства» -> «C/C++» -> «Предварительно скомпилированные заголовки» -> выберите «Не использовать предварительно скомпилированные заголовки в предварительно скомпилированном заголовке».
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top