устарело предупреждение - PullRequest
62 голосов
/ 18 августа 2008

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

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

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

Ответы [ 10 ]

115 голосов
/ 18 августа 2008

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

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

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

25 голосов
/ 18 августа 2008

Ну, вы можете добавить:

#pragma warning (disable : 4996)

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

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

13 голосов
/ 12 ноября 2008

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

8 голосов
/ 09 ноября 2011

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

#ifdef _WIN32
#define _CRT_SECURE_NO_DEPRECATE
#endif
4 голосов
/ 15 июля 2017

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

Меню \ Проект \ [ProjectName] Свойства ... Alt + F7

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

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

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

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

4 голосов
/ 18 сентября 2008

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

1 голос
/ 20 марта 2017

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

#define _CRT_SECURE_NO_WARNINGS

Затем скомпилируется.

1 голос
/ 04 февраля 2016

Многие из безопасных функций 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

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

1 голос
/ 24 февраля 2015

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

#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
0 голосов
/ 30 декабря 2014

У меня тоже такая же проблема. Когда я пытаюсь добавить библиотеку 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 ++ -> Предварительно скомпилированные заголовки -> Выберите Не использовать предварительно скомпилированные заголовки в предварительно скомпилированных заголовках.
...