Y at-il un moyen d'utiliser fopen_s () avec GCC ou au moins créer un #define à ce sujet?

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

  •  19-09-2019
  •  | 
  •  

Question

compilateur MSVC dit que fopen() est dépréciée, et recommande l'utilisation de fopen_s().

Est-il possible d'utiliser fopen_s() et encore portable?

Des idées pour un #define?

Était-ce utile?

La solution

Les fonctions de *_s de Microsoft sont non portable, je l'habitude d'utiliser des fonctions équivalentes C89 / C99 et désactiver les avertissements relatifs à l'obsolescence (#define _CRT_SECURE_NO_DEPRECATE).

Si vous insistez, vous pouvez utiliser une fonction d'adaptation (pas nécessairement une macro!) Que les délégués fopen() sur les plates-formes qui ne sont pas fopen_s(), mais vous devez faire attention à la carte des valeurs de code errno_t retour de 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;
}

Cependant, je ne vois pas comment fopen_s() est plus sûr que fopen(), donc je vais habituellement pour la portabilité.

Autres conseils

si vous utilisez C11, fopen_s est une bibliothèque standard:

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

gcc vous devez utiliser le paramètre de --std=C11.

Dans le code C / C ++,

#ifdef __unix
#define fopen_s(pFile,filename,mode) ((*(pFile))=fopen((filename),(mode)))==NULL
#endif

Dans Makefile

CFLAGS += -D'fopen_s(pFile,filename,mode)=((*(pFile))=fopen((filename),(mode)))==NULL'

Attention, que le succès fopen_s retour 0 en retour fopen un pointeur de fichier non nul. Par conséquent, il est nécessaire d'ajouter « == NULL » à la fin de la macro, par exemple:.

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

La plupart des fonctions sécurisées de Microsoft figurent à l'annexe K de la norme C11, mais il est pas largement pris en charge, si la portabilité est toujours un problème. Il est nécessaire pour l'amélioration de la sécurité dans certaines applications; peut-être le soutien permettra d'améliorer à l'avenir.

Je le passé, je l'ai fait comme ceci:

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

La macro est simple et simple, assez bon pour quelque chose de rapide et sale, mais il ne fournit pas le comportement d'exception de fopen_s, et il ne fournira pas la sécurité de la fonction réelle de fopen_s.

L'approche de la fonction de B ci-dessus reproduit @ Alex partiellement le bon comportement en cas d'échec; il retourne errno (= EINVAL). Son approche pourrait être élargie en générant un exception de paramètre non valide à reproduire plus complètement le comportement de fopen_s.

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

https://en.cppreference.com/w/c/io / fopen il est possible d'activer * _S fonctions de la bibliothèque standard:

  

Comme avec toutes les fonctions hors limites vérifiées, fopen_s est uniquement assuré d'être disponible si __STDC_LIB_EXT1__ est définie par la mise en oeuvre et si l'utilisateur définit __STDC_WANT_LIB_EXT1__ à l'entier 1 constante avant d'inclure <stdio.h>.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top