Gibt es eine Möglichkeit fopen_s () mit GCC zu verwenden oder zumindest schafft eine #define darüber?

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

  •  19-09-2019
  •  | 
  •  

Frage

MSVC Compiler sagt, dass fopen() veraltet ist, und empfiehlt die Verwendung von fopen_s().

Gibt es eine Möglichkeit zur Verwendung fopen_s() und noch tragbar sein?

Alle Ideen für eine #define?

War es hilfreich?

Lösung

Microsofts *_s Funktionen sind portabel, ich äquivalente C89 / C99-Funktionen in der Regel verwenden und deaktivieren deprecation Warnungen (#define _CRT_SECURE_NO_DEPRECATE).

Wenn Sie darauf bestehen, können Sie eine Adapterfunktion verwenden (nicht unbedingt ein Makro!), Dass die Delegierten auf Plattformen fopen() die fopen_s() nicht haben, aber man muss vorsichtig sein, Werte von errno_t Return-Code von errno abzubilden.

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

Allerdings sehe ich nicht, wie fopen_s() ist mehr sicherer als fopen(), so dass ich in der Regel für die Portabilität gehen.

Andere Tipps

Wenn Sie C11 verwenden, fopen_s ist eine Standardbibliothek:

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

in gcc müssen Sie --std=C11 Parameter verwenden.

In C / C ++ Code,

#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'

Achtung, dass auf Erfolg fopen_s 0 zurück, während fopen Rückkehr eine von Null verschiedene Dateizeiger. Daher ist es notwendig, „== NULL“ bis zum Ende des Makro hinzufügen, z.

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

Viele von Microsofts sicherer Funktionen sind in Anhang K des C11-Standard enthalten, aber es ist nicht weit unterstützt wird, so Portabilität immer noch ein Thema ist. Es besteht ein Bedarf für die Verbesserung der Sicherheit in einigen Anwendungen; vielleicht wird die Unterstützung in der Zukunft verbessern.

ich die Vergangenheit, ich habe es wie folgt aus:

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

Das Makro ist einfach und geradlinig, gut genug für etwas schnell und schmutzig, aber es bietet keine Ausnahme Verhalten von fopen_s, und es wird die Sicherheit der realen fopen_s Funktion nicht zur Verfügung stellen.

@ Alex B-Funktionsannäherung oben teilweise reproduziert das richtige Verhalten bei einem Fehler; er kehrt errno (= EINVAL). Sein Ansatz könnte weiter ausgebaut werden, indem die Erzeugung eine ungültiger Parameter Ausnahme , um mehr vollständig das Verhalten von fopen_s zu reproduzieren.

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

Accroding https://en.cppreference.com/w/c/io / fopen es ist möglich * zu ermöglichen _s Funktionen auf der Standardbibliothek:

  

Wie bei allen Grenzen überprüften Funktionen wird fopen_s nur verfügbar sein garantiert, wenn __STDC_LIB_EXT1__ durch die Implementierung definiert ist und wenn der Benutzer definiert __STDC_WANT_LIB_EXT1__ auf den Integer-Konstante 1 vor einschließlich <stdio.h>.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top