로깅 도우미 기능에서 strerror_r을 사용하고 있습니다. 설명서 페이지에서 설명하는 것처럼이 함수에는 두 가지 버전이 있습니다. POSIX 버전은 int를 반환합니다. GNU 버전은 문자열 (char *)을 반환합니다. 이와 같이알파로 리눅스에서 strerror_r이 잘못 선언되었습니다.
, 내 C++ 코드를 더 휴대용이다, 나는이 비슷한 코드 블록 그래서 : 위의 코드 블록에서
char buffer[1000];
int size = 1000;
int result = 0;
char* msg = buffer;
buffer[0] = '\0';
#ifdef _GNU_SOURCE
msg = strerror_r(err, buffer, size);
#else
result = strerror_r(err, buffer, size);
if (result != 0)
{
sprintf(buffer, "unknown error: %d", err);
}
#endif
LogToFile(msg);
를, 그것은 존재에 따라 strerror_r
의 버전 중 하나를 사용합니다 _GNU_SOURCE
인데, libstdC++에서 필요하기 때문에 항상 g ++로 설정됩니다. Mac 및 Unix의 다른 변형에서는 POSIX 버전을 사용합니다.
이제이 코드는 오늘까지 오랫동안 잘 진행되어 왔습니다. 사용자는 Alpine Linux에 내 코드를 컴파일하려고하고이 라인에 매핑 strerror_r
main.cpp:16:21 error: invalid conversion from 'int' to 'char*' [-fpermissive]
사용하여 라인에 오늘이 컴파일러 오류를보고 :
#ifdef _GNU_SOURCE
msg = strerror_r(err, buffer, size);
알이 플랫폼에 /usr/include/string.h
에서 피크 촬영을 다음과 같습니다 :
#if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \
|| defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \
|| defined(_BSD_SOURCE)
...
int strerror_r (int, char *, size_t);
...
#endif
어떤 컴파일러 환경이 사용 되더라도, strerror_r의 n은 int를 리턴하는 POSIX 버전입니다. 그래서 그 오류가 발생한 이유를 설명합니다.
사용자에게 수동으로 #undef _GNU_SOURCE
을 입력하거나 소스를 수정할 필요가 없어도 코드를 이식 가능한 상태로 유지하려면 어떻게해야합니까? _GNU_SOURCE를 전역 적으로 정의 해제하는 것은 C++ (위에서 언급 한 바와 같이 libstdC++에서 필요함)이기 때문에 시작하지 않을 가능성이 높습니다. 테스트 할 수있는 다른 매크로 조합이 있는지 알아보기 위해 노력하고 있지만 분명히 알 수있는 것은 없습니다. 당신은 C를 활용할 수
공식 매크로 검사 :
그리고하고는 사용에 조건부 컴파일을 제거)는'(_POSIX_C_SOURCE> = 200112L || _XOPEN_SOURCE> = 600) &&!입니다. _GNU_SOURCE'가 POSIX 버전이 제공되면 true이고, 그렇지 않으면 GNU 버전이 제공됩니다. 즉, GNU 버전이 제공되는지 확인하기에 충분해야하며 Alpine Linux의 C 라이브러리는 버그가 있거나 오래된 것으로 보입니다. –
자신의 기능으로 감싸십시오. 두 가지 변형을 사용할 수있을만큼 유연하게 만듭니다. –
@ n.m. 당신은 정교 할 수 있습니까? 함수에 이미 포장되어 있습니다 ... – selbie