функции fopen устаревшие предупреждения


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

1>foo.cpp(5) : warning C4996: 'fopen' was declared deprecated
1>        c:program filesmicrosoft visual studio 8vcincludestdio.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 57

10 ответов:

похоже, что 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, потому что это часть стандартов ISO C & C++).

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

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

#ifdef _WIN32
#define _CRT_SECURE_NO_DEPRECATE
#endif

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

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

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

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

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

#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 не реализуются.

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

#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++ -> предварительно скомпилированные заголовки -> не использовать предварительно скомпилированные заголовки выбрать в Предкомпилированного заголовка.