C'è un modo per utilizzare fopen_s () con GCC o almeno creare un # define a questo proposito?

StackOverflow https://stackoverflow.com/questions/1513209

  •  19-09-2019
  •  | 
  •  

Domanda

MSVC compilatore dice che fopen() è deprecato, e raccomanda l'uso di fopen_s().

C'è un modo per utilizzare fopen_s() ed essere ancora portatile?

Tutte le idee per un #define?

È stato utile?

Soluzione

funzioni *_s di Microsoft sono portabile, io di solito uso equivalenti funzioni C89 / C99 e disabilitare gli avvisi di deprecazione (#define _CRT_SECURE_NO_DEPRECATE).

Se si insiste, è possibile utilizzare una funzione di adattatore (non necessariamente una macro!) Che i delegati fopen() su piattaforme che non hanno fopen_s(), ma è necessario fare attenzione per mappare i valori di codice di ritorno errno_t da 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;
}

Tuttavia, non riesco a vedere come fopen_s() è più sicuro rispetto fopen(), così io di solito vado per la portabilità.

Altri suggerimenti

se si utilizza C11, fopen_s è una libreria standard:

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

in gcc è necessario utilizzare il parametro --std=C11.

Nel codice 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'

L'attenzione che in caso di successo fopen_s ritorno 0 mentre fopen restituire un puntatore di file diverso da zero. Pertanto è necessario aggiungere "== NULL" al fine della macro, per esempio:.

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

Molte delle funzioni sicure di Microsoft sono incluse nell'allegato K dello standard C11, ma non è ampiamente supportato, quindi la portabilità è ancora un problema. V'è una necessità per il miglioramento della sicurezza in alcune applicazioni; forse il supporto sarà migliorare in futuro.

I passato, l'ho fatto in questo modo:

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

La macro è semplice e diretto, abbastanza buono per qualcosa di veloce e sporco, ma non fornisce il comportamento eccezione di fopen_s, e non fornirà la sicurezza della funzione fopen_s reale.

di @alex B approccio funzione sopra parzialmente riproduce il corretto comportamento in caso di errore; torna errno (= EINVAL). Il suo approccio potrebbe essere esteso ulteriormente generando un eccezione parametro non valido per riprodurre più pienamente il comportamento di fopen_s.

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

https://en.cppreference.com/w/c/io / fopen è possibile abilitare * _S funzioni della libreria standard:

  

Come per tutte le funzioni di controllo dei limiti, fopen_s è garantita solo essere disponibile se __STDC_LIB_EXT1__ è definito dalla attuazione e se l'utente definisce __STDC_WANT_LIB_EXT1__ alla costante intera 1 prima di includere <stdio.h>.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top