有没有办法在GCC中使用fopen_s()或者至少创建一个#define?

时间:2009-10-03 08:40:35

标签: c gcc visual-c++ fopen

MSVC编译器说不推荐fopen(),建议使用fopen_s()

有没有办法使用fopen_s()并仍然可移植?

#define的任何想法?

6 个答案:

答案 0 :(得分:26)

Microsoft的*_s函数不可移植,我通常使用等效的C89 / C99函数并禁用弃用警告(#define _CRT_SECURE_NO_DEPRECATE)。

如果你坚持,你可以使用在没有fopen()的平台上委派fopen_s()的适配器功能(不一定是宏!),但你必须小心映射{的值{1}}从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()更安全,所以我通常会寻求便携性。

答案 1 :(得分:10)

如果您使用的是C11,fopen_s是标准库:

http://en.cppreference.com/w/c/io/fopen

gcc中的

您需要使用--std=C11参数。

答案 2 :(得分:7)

在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_s返回0而fopen返回非零文件指针。因此,有必要在宏的末尾添加“== NULL”,例如:

if (fopen_s(&pFile,filename,"r")) perror("cannot open file");

答案 3 :(得分:2)

Microsoft的许多安全功能都包含在C11标准的附录K中,但它没有得到广泛支持,因此可移植性仍然是一个问题。在某些应用中需要提高安全性;也许这种支持将来会有所改善。

我过去,我是这样做的:

  #define fopen_s(fp, fmt, mode)          *(fp)=fopen( (fmt), (mode))

宏很简单直接,对于快速和脏的东西都足够好,但它不能提供fopen_s的异常行为,并且它不会提供真正的fopen_s函数的安全性。 / p> 上面的@Alex B&#39功能方法部分地再现了失败时的正确行为;他返回errno(= EINVAL)。他的方法可以通过生成无效参数异常进一步扩展,以更充分地再现fopen_s的行为。

答案 4 :(得分:0)

根据https://en.cppreference.com/w/c/io/fopen 可以在stdc库上启用* _s功能

  

”“与所有边界检查函数一样,只有在实现中定义了 STDC_LIB_EXT1 并且用户将 STDC_WANT_LIB_EXT1 定义为整数常量时,才能保证fopen_s可用。 1包括stdio.h。”

答案 5 :(得分:0)

#define fopen_s(fp, fmt, mode)  ({\
    *(fp)=fopen( (fmt), (mode));\
    (*(fp) ) ? 0:errno;\
})