¿Hay una manera de utilizar fopen_s () con GCC o al menos crear un #define respecto?

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

  •  19-09-2019
  •  | 
  •  

Pregunta

MSVC compilador dice que fopen() está en desuso, y recomienda el uso de fopen_s().

¿Hay alguna manera de utilizar fopen_s() y todavía ser portátil?

¿Alguna idea para un #define?

¿Fue útil?

Solución

*_s funciones de Microsoft son no portables, que suelen utilizar las funciones C89 / C99 equivalentes y desactivar las advertencias de obsolescencia (#define _CRT_SECURE_NO_DEPRECATE).

Si insiste, se puede utilizar una función de adaptador (no necesariamente una macro!) Que los delegados fopen() en plataformas que no tienen fopen_s(), pero hay que tener cuidado al asignar los valores de código de retorno de 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;
}

Sin embargo, no veo cómo fopen_s() es más segura que la fopen(), así que suelo ir para la portabilidad.

Otros consejos

si está utilizando C11, fopen_s es una biblioteca estándar:

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

en gcc es necesario utilizar el parámetro --std=C11.

En código C / C ++,

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

En Makefile

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

La atención de que en caso de éxito fopen_s devolver 0, mientras que fopen devuelve un puntero a un archivo distinto de cero. Por lo tanto es necesario añadir "== NULL" al final de macro, por ejemplo:.

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

Muchas de las funciones de seguridad de Microsoft están incluidas en el Anexo K de la norma C11, pero no se admite ampliamente, por lo que la portabilidad sigue siendo un problema. Hay una necesidad para la mejora de la seguridad en algunas aplicaciones; tal vez el apoyo mejorará en el futuro.

Yo el pasado, lo hice de esta manera:

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

La macro es simple y sencillo, lo suficientemente bueno para algo rápido y sucio, pero no proporciona el comportamiento excepción de fopen_s, y no va a proporcionar la seguridad de la función fopen_s real.

enfoque de la función de @Alex B anterior parcialmente reproduce el comportamiento adecuado en caso de fallo; regresa errno (= EINVAL). Su enfoque podría ampliarse aún más mediante la generación de un excepción parámetro no válido para reproducir mejor el comportamiento de fopen_s.

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

https://en.cppreference.com/w/c/io / fopen es posible habilitar * _S funciones de la biblioteca estándar:

  

Al igual que con todas las funciones grada-controladas, fopen_s sólo se garantiza que esté disponible si __STDC_LIB_EXT1__ se define por la aplicación y si el usuario define __STDC_WANT_LIB_EXT1__ al entero 1 constante antes de incluir <stdio.h>.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top