簡體   English   中英

有沒有辦法將 fopen_s() 與 GCC 一起使用,或者至少創建一個關於它的#define?

[英]Is there a way to use fopen_s() with GCC or at least create a #define about it?

MSVC 編譯器說fopen()已棄用,並建議使用fopen_s()

有什么方法可以使用fopen_s()並且仍然可以移植嗎?

#define有什么想法嗎?

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

如果您堅持,您可以使用適配器函數(不一定是宏!)在沒有fopen_s()的平台上委托fopen() ) ,但您必須小心從errno映射errno_t返回代碼的值。

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

在 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");

如果您使用的是 C11, fopen_s是一個標准庫

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;\
})

根據https://en.cppreference.com/w/c/io/fopen可以在標准庫上啟用 *_s 函數:

與所有邊界檢查函數一樣,只有在實現定義了__STDC_WANT_LIB_EXT1__並且用戶在包含<stdio.h>之前將__STDC_LIB_EXT1__定義為整數常量1時,才保證fopen_s可用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM