有没有办法使用fopen_s()与海湾合作委员会或至少创建一个关于它的#define的方法吗?
-
19-09-2019 - |
题
MSVC编译器说fopen()
已过时,建议使用fopen_s()
的。
有没有办法使用fopen_s()
,仍然是便携式?
有一个#define
任何想法?
解决方案
微软的*_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”,以宏末尾,e.g:
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的上述部分功能的方法再现失败的正确行为;他将返回错误号(= EINVAL)。他的方法可能进一步通过产生的无效的参数异常延长以更充分地重现fopen_s的行为。
#define fopen_s(fp, fmt, mode) ({\
*(fp)=fopen( (fmt), (mode));\
(*(fp) ) ? 0:errno;\
})
Accroding到 https://en.cppreference.com/w/c/io / FOPEN 这是可能的,以使* _s上的标准库函数:
对于所有的边界检查功能,
fopen_s
仅保证可供如果__STDC_LIB_EXT1__
由实现和定义如果用户包括__STDC_WANT_LIB_EXT1__
之前定义1
为整数常数<stdio.h>
。