質問
の上 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.'
これを防ぐにはどうすればよいですか?
解決
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 はこの例では起こりません。これは fopen の一部であるためです) C および C++ ISO 標準)。
これはマイクロソフトが生意気なだけです。「非推奨」とは、標準化委員会の決定に従って、標準言語/標準ライブラリの将来のバージョンでは提供されない可能性がある言語機能を意味します。たとえそのアドバイスがどれほど十分に根拠のあるものであっても、「私たちは一方的に、あなたがそのアドバイスを使用すべきではないと考えています」という意味ではありませんし、また、そうすべきではありません。
コードが別の OS (Mac OS X、Linux など) を対象としている場合は、以下を使用できます。
#ifdef _WIN32
#define _CRT_SECURE_NO_DEPRECATE
#endif
次のような移植性ライブラリの使用を検討してください。 口先だけの または Apacheポータブルランタイム. 。これらは通常、このような呼び出しに代わる安全でポータブルな手段を提供します。これらの安全でない呼び出しは、ほとんどの最新の環境では非推奨になっているため、これは良いことでもあります。
VisualStdio2008を使用しています。この場合、私はよく設定します 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
そうすればコンパイルされます。
fopen_s() を含む Microsoft のセキュア関数の多くは C11 の一部であるため、移植可能になるはずです。安全な関数は例外動作が異なり、場合によっては戻り値も異なることに注意してください。さらに、これらの関数は標準化されているものの、 オプション 標準 (Annex 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++] -> [プリコンパイル済みヘッダー] -> [プリコンパイル済みヘッダーでプリコンパイル済みヘッダーを使用しない] を選択します。