fopen弃用警告

时间:2008-08-18 09:38:59

标签: visual-c++ fopen deprecated

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 个答案:

答案 0 :(得分:115)

看起来微软已弃用大量使用缓冲区来提高代码安全性的调用。但是,他们提供的解决方案并不便携。无论如何,如果您对使用其安全版本的呼叫不感兴趣(例如 fopen_s ),则需要在包含的头文件之前放置 _CRT_SECURE_NO_DEPRECATE 的定义。例如:

#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>

也可以将预处理程序指令添加到项目设置中,以便在项目下的所有文件上实现它。为此,请将 _CRT_SECURE_NO_DEPRECATE 添加到项目属性 - &gt;配置属性 - &gt; C / C ++ - &gt;预处理器 - &gt;预处理器定义

答案 1 :(得分:25)

你可以添加一个:

#pragma warning (disable : 4996)

在你使用fopen之前,你是否考虑过使用fopen_s作为警告?它返回一个错误代码,允许您检查函数调用的结果。

仅禁用已弃用的功能警告的问题是,Microsoft可能会在更高版本的CRT中删除相关功能,从而破坏您的代码(如下面的注释中所述,这不会发生在fopen的这个实例中,因为它是C&amp; C ++ ISO标准的一部分。)

答案 2 :(得分:13)

这只是微软的厚颜无耻。 “弃用”意味着标准委员会规定的标准语言/标准库的未来版本中可能未提供的语言特征。它没有,或者不应该意味着“我们,单方面地,不认为你应该使用它”,无论这个建议有多么有根据。

答案 3 :(得分:8)

如果您的代码适用于其他操作系统(如Mac OS X,Linux),则可以使用以下命令:

#ifdef _WIN32
#define _CRT_SECURE_NO_DEPRECATE
#endif

答案 4 :(得分:4)

考虑使用glibapache portable runtime等可移植性库。这些通常为这些呼叫提供安全,便携的替代方案。这也是一件好事,因为在大多数现代环境中不推荐使用这些不安全的调用。

答案 5 :(得分:4)

我正在使用VisualStdio 2008。 在这种情况下,我经常设置 Preprocessor Definitions

  

菜单\项目\ [ProjectName]属性... Alt + F7

如果单击此菜单或在项目窗口中按Alt + F7,则可以看到&#34;属性页&#34; 窗口。

然后看窗口左侧的菜单。

  

配置属性\ C / C ++ \预处理器

然后将 _CRT_SECURE_NO_WARNINGS 添加到 \预处理程序定义

答案 6 :(得分:1)

微软的许多安全功能,包括fopen_s(),都是C11的一部分,因此它们现在应该是可移植的。您应该意识到安全功能在异常行为和有时返回值方面有所不同。此外,您需要注意,虽然这些功能是标准化的,但它是标准(附件K)的可选部分,至少glibc(默认在Linux上)和FreeBSD的libc不实现。

然而,我解决了这个问题已有几年了。我发布了一组更大的转换宏here.,针对您的问题,请将以下代码放入包含文件中,并将其包含在源代码中:

#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

当然,这种方法并没有实现预期的异常行为。

答案 7 :(得分:1)

如果您希望它在许多平台上使用,您可以像评论一样使用定义如下:

#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

答案 8 :(得分:1)

对于那些使用Visual Studio 2017版本的人来说,运行不安全操作所需的预处理器定义似乎已经改变。改为使用:

#define _CRT_SECURE_NO_WARNINGS

然后编译。

答案 9 :(得分:0)

我也遇到了同样的问题。当我尝试添加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  

我还使用了前面提到的预处理程序指令。但这并没有解决问题。

我通过以下方式解决了这个问题:

  • 转到“属性” - &gt; C / C ++ - &gt;预编译标题 - &gt;在预编译标题中选择不使用预编译标题。