Gibt es eine Möglichkeit fopen_s () mit GCC zu verwenden oder zumindest schafft eine #define darüber?
-
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
?
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-Konstante1
vor einschließlich<stdio.h>
.