それについての#defineを作成し、少なくともGCCとのfopen_s()を使用するかする方法はありますか?
-
19-09-2019 - |
質問
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()
より任意のより安全であるかを確認することができないので、私は通常、移植のために行く。
他のヒント
あなたはC11を使用している場合は、fopen_s
は標準ライブラリです。
http://en.cppreference.com/w/c/io/fopenする
gcc
にあなたは--std=C11
パラメータを使用する必要があります。
C / C ++コードでは、
#ifdef __unix
#define fopen_s(pFile,filename,mode) ((*(pFile))=fopen((filename),(mode)))==NULL
#endif
Makefileで
CFLAGS += -D'fopen_s(pFile,filename,mode)=((*(pFile))=fopen((filename),(mode)))==NULL'
fopenをゼロ以外のファイルポインタを返しながら成功fopen_sに0を返すことを注意。したがって、例えば、マクロの末尾に「== NULL」を追加する必要がある:
if (fopen_s(&pFile,filename,"r")) perror("cannot open file");
多くは、C11規格の附属書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;\
})
https://en.cppreference.com/w/c/ioにAccroding / fopenをする それが標準ライブラリに* _s機能を有効にすることが可能です。
すべての境界・チェック機能を有するように、
fopen_s
のみ__STDC_LIB_EXT1__
を実装することによって、ユーザが__STDC_WANT_LIB_EXT1__
を含む前整数定数1
に<stdio.h>
を定義した場合に定義されている場合に使用可能であることが保証される。