устарело предупреждение

В компиляторе 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.'

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

18.08.2008 09:38:58
10 ОТВЕТОВ
РЕШЕНИЕ

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

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

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

126
18.08.2008 09:39:16
Вы, вероятно, должны сделать что-то вроде этого: #ifdef _WIN32 #define _CRT_SECURE_NO_DEPRECATE #endif #include <stdio.h> Потому что другим платформам это не нужно определять во время компиляции.
markwatson 13.08.2010 19:08:48
@markwatson Лучшим охранником будет проверка #ifdef _MSC_VER.
MicroVirus 3.06.2016 01:47:12

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

#pragma warning (disable : 4996)

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

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

28
18.09.2014 13:40:40
Я мог бы использовать fopen_s , но так как в нем появился некоторый код, который я хотел сделать как можно более переносимым, я не предпочитаю это решение. Мне трудно поверить, что Microsoft полностью удалит вызовы стандартной библиотеки. Они могут сделать их довольно сложными в использовании, но им нужно будет хранить их для старого кода.
Ashwin Nanjappa 18.08.2008 13:13:14
«Microsoft может удалить соответствующую функцию в более поздней версии CRT», - если они больше не хотят реализовывать стандарты C или C ++.
Steve Jessop 25.05.2009 13:15:58
Некоторые люди нацелены и на платформы без MS. И со многими из этих функций, нет действительно заметного усиления безопасности.
sstn 11.08.2011 07:49:05
Для будущих googlers: In this context, "deprecated" just means that a function's use is not recommended; it does not indicate that the function is scheduled to be removed from the CRT.- msdn ++++
Navin 19.03.2013 20:38:31
В VS2013 мне нужно было использовать, #pragma warning(disable:4996)потому что предложенный _CRT_SECURE_NO_WARNINGSи _CRT_SECURE_NO_DEPRECATEоба не работали. В #defines - видимому, работали в других контекстах, поэтому хедз-ап , что это , кажется, непоследовательно реализован.
Bill Weinman 13.05.2014 04:01:14

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

4
18.09.2008 11:15:58
Портативная альтернатива Microsoft, один-офф, не вполне соответствует стандартам, не переносимая реализация опционной функции Приложение K fopen_s()является стандартной функцией C fopen().
Andrew Henle 4.02.2020 12:26:18

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

13
12.11.2008 17:34:49
Значение английского слова «deprecate» как раз и является вторым: «мы думаем, что вы не должны его использовать». Но на компьютерном языке в последнее время оно стало иметь гораздо более слабое значение: «Возможно, было бы неразумно использовать его, потому что мы как бы думаем об его удалении и предоставили что-то, что считаем лучше».
Steve Jessop 25.05.2009 13:22:03

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

#ifdef _WIN32
#define _CRT_SECURE_NO_DEPRECATE
#endif
9
20.02.2015 23:02:21

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

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

#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
1
24.02.2015 09:57:23
Ваш комплекс #IF адресован только платформам, а не версиям компилятора. Как насчет #if (defined(_MSC_VER) && (_MSC_VER >= 1600) ) ... #ELSE ...того, чтобы охватить все дела, верно?
riderBill 4.02.2016 02:46:42
_MSC_VER = 1600, возможно, не первая версия, которая устарела fopen () и т. Д. Это была первая версия, в которой я столкнулся с проблемой.
riderBill 4.02.2016 02:49:45
Похоже, первой версией MSVC с (некоторыми из) защищенными функциями была 2005, _MSC_VER = 1400.
riderBill 6.02.2016 23:56:29

Многие из безопасных функций 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
28.08.2017 10:53:11
MS _s- это не то же самое, что интерфейс C11 для проверки границ в целом. Некоторые имеют одинаковую синатуру, некоторые нет. Поскольку этот интерфейс является необязательным, его поддерживают лишь немногие реализации, потому что он по большей части не нужен. И ваш код - C ++, а не C, на который вы ссылаетесь в тексте.
too honest for this site 17.09.2017 16:30:06
@ Олаф: Хм. Я не могу обратиться к проверке границ, кроме как указать на предостережение о поведении исключений.
riderBill 19.09.2017 01:13:57
Вы правы в том, что я процитировал стандарт C11 (в отличие от C ++ 14 или 17). Функции доступны в последних версиях компиляторов Microsoft C ++. Оказывается, что Приложение K не поддерживается широко за пределами MSVS. Джонатан Леффлер прокомментировал здесь, что версии MS на самом деле не соответствуют спецификациям Приложения K. Так много для мобильности.
riderBill 19.09.2017 01:14:50
Я был бы признателен , если вы читали мои комментарии полностью . MSVC на самом деле использует не BCI, а собственный суп. MSVC не отвечает требованиям по меньшей мере 18 лет, и было совершенно ясно, что они не намерены, по крайней мере, включить обязательные функции C99, такие как VLA, которые поддерживаются каждым современным компилятором уже много лет (включая основные встроенные).
too honest for this site 19.09.2017 01:26:37
Спрашивающий отметил тег Visual C ++. Я скопировал код из файла C ++ большего размера. Для C я думаю, что include будет stdio.h и string.h (однако в приведенном выше коде строки не используются). Мне не нужно использовать пространство имен std; утверждение - это действительно в C? Я думаю, что inline extern ... должен быть статическим inline в C, чтобы избежать проблем с компоновщиком. Я не пишу много кода C в эти дни. Добавить комментарий, если я ошибаюсь.
riderBill 19.09.2017 01:26:52

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

#define _CRT_SECURE_NO_WARNINGS

Это будет компилироваться тогда.

1
20.03.2017 16:03:40
Это не похоже на работу для меня. Все еще получите ошибки компиляции для freopen.
Levi Roberts 27.10.2018 16:38:32

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

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

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

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

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

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

5
15.07.2017 03:35:23
Пожалуйста, ознакомьтесь с первым ответом на этот вопрос. На этот вопрос уже дан ответ, очевидно, вы можете добавить свой ответ здесь. Но вам нужно понять некоторые моменты, прежде чем ответить. Во-первых, не добавляйте ответ, который ранее был добавлен с тем же кодом или предложением. Во-вторых, не добавляйте слишком сложный ответ, если пользователь задал очень конкретный вопрос о проблеме и что ему нужно для ее решения. В-третьих, вы можете добавить комментарий, если хотите что-то предложить относительно ответа или вопроса.
ankit suthar 15.07.2017 04:48:03
Это единственный ответ, который работал для меня в Visual Studio 2017. #defineоставил много ошибок C4996. (@ankitsuthar ваш комментарий кажется мне неуместным. Этот ответ лаконичен, работает и отличается важными деталями от других.)
Bob Stein 6.02.2019 21:02:41
это сработало для меня, спасибо @Bryant
N.SANDEEP REDDY sandeep 4.03.2020 07:07:56