题
在 Visual Studio 2005 C++ 编译器, ,当我的代码使用 福彭 和这样的电话。
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.'
我该如何防止这种情况?
解决方案
看起来微软已经弃用了很多使用缓冲区来提高代码安全性的调用。然而,他们提供的解决方案不可移植。无论如何,如果您对使用他们的调用的安全版本不感兴趣(例如 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 标准)。
这只是微软的厚颜无耻而已。“已弃用”意味着根据标准委员会的规定,标准语言/标准库的未来版本中可能不会提供某种语言功能。它并不也不应该意味着“我们单方面认为您不应该使用它”,无论该建议有多么有理有据。
如果您的代码适用于不同的操作系统(例如 Mac OS X、Linux),您可以使用以下内容:
#ifdef _WIN32
#define _CRT_SECURE_NO_DEPRECATE
#endif
考虑使用像这样的可移植库 油嘴滑舌 或者 Apache 便携式运行时. 。这些通常为此类呼叫提供安全、便携的替代方案。这也是一件好事,因为这些不安全的调用在大多数现代环境中已被弃用。
我正在使用 VisualStdio 2008。在这种情况下我经常设置 Preprocessor Definitions
菜单\项目\[项目名称]属性...Alt+F7
如果单击此菜单或在项目窗口中按 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 上的默认值)和 FreeBSD 的 libc 没有实现。
然而,我与这个问题斗争了几年。我发布了一组更大的转换宏 这里。, ,对于您眼前的问题,请将以下代码放入包含文件中,并将其包含在您的源代码中:
#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++ -> 预编译头 -> 在预编译头中选择不使用预编译头。