MSVC コンパイラは、これfopen()
は非推奨であると述べており、 fopen_s()
.
fopen_s()
ポータブルで使用する方法はありますか?
のアイデアはあり#define
ますか?
MSVC コンパイラは、これfopen()
は非推奨であると述べており、 fopen_s()
.
fopen_s()
ポータブルで使用する方法はありますか?
のアイデアはあり#define
ますか?
Microsoft の*_s
関数は移植性がありません。私は通常、同等の C89/C99 関数を使用し、非推奨の警告を無効にします ( #define _CRT_SECURE_NO_DEPRECATE
)。
fopen()
主張する場合は、を持たないプラットフォームでデリゲートするアダプタ関数 (必ずしもマクロである必要はありません!) を使用できますが、からの戻りコードfopen_s()
の値をマッピングするように注意する必要があります。errno_t
errno
errno_t fopen_s(FILE **f, const char *name, const char *mode) {
errno_t ret = 0;
assert(f);
*f = fopen(name, mode);
/* Can't be sure about 1-to-1 mapping of errno and MS' errno_t */
if (!*f)
ret = errno;
return ret;
}
fopen_s()
ただし、が よりも安全であることがわかりませんfopen()
。そのため、通常は移植性を重視します。
C/C++ コードでは、
#ifdef __unix
#define fopen_s(pFile,filename,mode) ((*(pFile))=fopen((filename),(mode)))==NULL
#endif
メイクファイル内
CFLAGS += -D'fopen_s(pFile,filename,mode)=((*(pFile))=fopen((filename),(mode)))==NULL'
成功すると、fopen_s は 0 を返しますが、fopen はゼロ以外のファイル ポインタを返すことに注意してください。したがって、マクロの最後に「==NULL」を追加する必要があります。例:
if (fopen_s(&pFile,filename,"r")) perror("cannot open file");
C11 を使用している場合fopen_s
は、標準ライブラリです。
http://en.cppreference.com/w/c/io/fopen
パラメータをgcc
使用する必要があり--std=C11
ます。
Microsoft のセキュア機能の多くは C11 標準の Annex K に含まれていますが、広くサポートされていないため、移植性は依然として問題です。一部のアプリケーションでは、セキュリティを強化する必要があります。今後、サポートが改善される可能性があります。
私は過去に、次のようにしました:
#define fopen_s(fp, fmt, mode) *(fp)=fopen( (fmt), (mode))
このマクロはシンプルで単純明快で、手早く汚いものには十分ですが、fopen_s の例外動作を提供せず、実際の fopen_s 関数のセキュリティを提供しません。
上記の @Alex B の関数アプローチは、失敗時の適切な動作を部分的に再現します。彼は errno (= EINVAL) を返します。fopen_s の動作をより完全に再現するために無効なパラメータの例外を生成することで、彼のアプローチをさらに拡張することができます。
#define fopen_s(fp, fmt, mode) ({\
*(fp)=fopen( (fmt), (mode));\
(*(fp) ) ? 0:errno;\
})