GCC와 함께 fopen_s ()를 사용하거나 적어도 #define을 만들 수있는 방법이 있습니까?
-
19-09-2019 - |
문제
MSVC 컴파일러가 말합니다 fopen()
더 이상 사용되지 않으며 사용을 권장합니다 fopen_s()
.
사용할 방법이 있습니까? fopen_s()
그리고 여전히 휴대 성이 있습니까?
A에 대한 아이디어 #define
?
해결책
마이크로 소프트 *_s
함수는 볼 수 없으며, 일반적으로 동등한 C89/C99 기능을 사용하고 감가 상각 경고를 비활성화합니다 (#define _CRT_SECURE_NO_DEPRECATE
).
당신이 주장하면, 당신은 대표하는 어댑터 기능 (반드시 매크로가 아닙니다!)을 사용할 수 있습니다. fopen()
없는 플랫폼에서 fopen_s()
, 그러나 당신은 값을 매핑하기 위해주의해야합니다. 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;
}
그러나 나는 방법을 보지 못한다 fopen_s()
보다 안전합니다 fopen()
, 그래서 나는 보통 이식성을 위해갑니다.
다른 팁
C11을 사용하는 경우 fopen_s
표준 라이브러리입니다.
http://en.cppreference.com/w/c/io/fopen
안에 gcc
사용해야합니다 --std=C11
매개 변수.
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'
성공시 FOPEN_S가 0을 반환하고 FOPEN은 0이 아닌 파일 포인터를 반환한다는주의를 기울입니다. 따라서 매크로 끝에 "== null"을 추가해야합니다.
if (fopen_s(&pFile,filename,"r")) perror("cannot open file");
C11 표준의 부록 K에 많은 Microsoft의 보안 기능이 포함되어 있지만 널리 지원되지 않으므로 휴대 성이 여전히 문제입니다. 일부 애플리케이션에서는 보안 개선이 필요합니다. 아마도 지원이 향후 개선 될 것입니다.
나는 과거, 나는 이것을처럼했다 :
#define fopen_s(fp, fmt, mode) *(fp)=fopen( (fmt), (mode))
매크로는 간단하고 간단하며 빠르고 더러운 무언가에 충분히 좋지만 Fopen_S의 예외 동작을 제공하지 않으며 실제 Fopen_S 기능의 보안을 제공하지 않습니다.
@Alex B의 기능 접근은 실패시 적절한 동작을 부분적으로 재현합니다. 그는 errno (= einval)를 반환합니다. 그의 접근 방식은 an을 생성함으로써 더욱 확장 될 수있다 잘못된 매개 변수 예외 fopen_s의 동작을보다 완전하게 재현하려면.
#define fopen_s(fp, fmt, mode) ({\
*(fp)=fopen( (fmt), (mode));\
(*(fp) ) ? 0:errno;\
})
accroding https://en.cppreference.com/w/c/io/fopen 표준 라이브러리에서 *_s 함수를 활성화 할 수 있습니다.
모든 경계 확인 된 함수와 마찬가지로
fopen_s
경우에만 사용할 수 있습니다__STDC_LIB_EXT1__
구현에 의해 정의되고 사용자가 정의하는 경우__STDC_WANT_LIB_EXT1__
정수 상수에1
포함하기 전에<stdio.h>
.