"#define _GNU_SOURCE"는 무엇을 의미하나?
오늘 나는 그 제품을 사용해야 했다.basename()
기능, 그리고man 3 basename
(여기) 내게 이상한 메시지를 주었다.
메모들
기본 이름()에는 위에서 설명한 POSIX 버전과 GNU 버전 등 두 가지 버전이 있다.
#define _GNU_SOURCE
#include <string.h>
이게 뭔지 궁금하다.#define _GNU_SOURCE
즉, GNU 관련 라이선스로 작성한 코드를 표시하지 않는가?아니면 단순히 컴파일러에게 "글쎄, 나도 알아, 이 기능 세트는 POSIX가 아니니까 휴대용은 아니지만, 어쨌든 사용하고 싶어."와 같은 것을 말하는 데 사용되는가?
만약 그렇다면, 한 기능 구현이나 다른 기능 구현을 위해 모호한 매크로를 정의해야 하는 대신에 사람들에게 다른 헤더를 주는 것은 어떨까?
컴파일러가 실행 가능한 기능과 연결해야 할 기능 구현을 어떻게 알 수 있을까?이것을 사용하는가?#define
또한?
나한테 조언해줄 사람 있어?
_GNU_SOURCE
면허증, 그리고 휴대 전화 코드 작성과 관련된 모든 것은 아무 관련이 없다.정의한 경우_GNU_SOURCE
, 얻을 수 있는 이점:
- 많은 비표준 GNU/리눅스 확장 기능에 액세스
- POSIX 표준에서 누락된 기존 기능에 대한 액세스(더 나은 대안으로 대체되거나 특정 레거시 구현과 연계되는 등 정당한 이유로 종종 사용됨)
- 휴대할 수 없지만 때때로 다음과 같은 시스템 유틸리티를 구현하는 데 필요한 낮은 수준의 기능에 대한 액세스
mount
ifconfig
등 - 많은 POSIX기능에대한 고장난 행동 지정.GNU사람들은 기능이 어떻게 행동해야 하는지에 대한 표준 위원회에 동의하지 않았고 그들 자신의 일을 하기로 결정했다.
이러한 것들을 알고 있는 한, 정의해 나가는 것이 문제가 되어서는 안 된다._GNU_SOURCE
, 그러나 정의하지 말고 정의하십시오._POSIX_C_SOURCE=200809L
또는_XOPEN_SOURCE=700
가능한 경우 프로그램을 휴대할 수 있는지 확인하십시오.
히히에서 것들이다._GNU_SOURCE
절대 사용해서는 안 되는 것은 위의 2번과 4번이다.
사용 가능한 모든 항목에 대한 정확한 세부 정보_GNU_SOURCE
문서화는 도움이 될 수 있다.
GNU 문서:
매크로: _GNU_SOURCE
이 매크로를 정의하면 모든 것이 포함된다.ISO C89, ISO C99, POSIX.1, POSIX.2, BSD, SVID, X/Open, LFS 및 GNU 확장.POSIX.1이 BSD와 충돌하는 경우, POSIX 정의가 우선한다.
기능 테스트 매크로의 Linux 맨 페이지:
_GNU_SOURCE
Defining this macro (with any value) implicitly defines _ATFILE_SOURCE, _LARGEFILE64_SOURCE, _ISOC99_SOURCE, _XOPEN_SOURCE_EXTENDED, _POSIX_SOURCE, _POSIX_C_SOURCE with the value 200809L (200112L in glibc versions before 2.10; 199506L in glibc versions before 2.5; 199309L in glibc ver‐ sions before 2.1) and _XOPEN_SOURCE with the value 700 (600 inglibc 버전 2.10 이전, glibc 버전 2.2 이전 500).또, 다양한 GNU 특화 확장도 노출된다.
glibc 2.19 이후 _GNU_SOURCE_SOURCE를 정의하면 _DEFAUR_SOURCE를 암묵적으로 정의하는 효과도 있다.2.20 이전 glibc 버전에서 _GNU_SOURCE_SOURCE를 정의하면 _BSD_SOURCE 및 _SVID_SOURCE를 암묵적으로 정의하는 효과도 있었다.
참고:_GNU_SOURCE
헤더 파일을 포함하기 전에 각 헤더가 기능을 사용하도록 정의해야 한다.예를 들면 다음과 같다.
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
...
_GNU_SOURCE
또한 다음을 사용하여 컴파일별로 활성화될 수 있다.-D
플래그:
$ gcc -D_GNU_SOURCE file.c
(-D
에 구체적이지 않다_GNU_SOURCE
그러나 어떤 매크로도 이와 같이 정의된다.
Google을 통한 일부 메일 목록에서:
glibc의 포함/특징을 보라.h:
_GNU_SOURCE 위의 모든 항목과 GNU 확장자.
즉, 이 모든 것을 가능하게 하는 것이다.
엄격한_ANSI, _ISOC99_SOURCE, _POSIX_SOURCE, _POSIX_C_SOURCE, _XOPEN_SOURCE_EXTEND, _LARGFILE64_SOURCE, _FILE_OFFSET_BITS=N, _BSD_SOURCE, _SVID_SOURCE
그래서 gcc를 위해 많은 편찬 깃발을 사용할 수 있다.
왜 사람들에게 다른 헤더를 주지 않는가?
그들은 이미 그것들을 가지고 있다; 헤더는 주제별로 파일로 나누어져 있기 때문에 필터링하려면 다른 차원이 필요하다.
나는 이름 대 신호 변환을 찾고 있었다.찾았다strsignal()
에<string.h>
. 맨 페이지는 다음과 같이 말한다.
sigabbrev_np(), sigdescr_np():
_GNU_SOURCE <<< not default
strsignal():
From glibc 2.10 to 2.31:
_POSIX_C_SOURCE >= 200809L <<< default, cf. XOPEN2K8 below
Before glibc 2.10:
_GNU_SOURCE
나는 이 부분을 전혀 신경 써 본 적이 없었다. sigabbrev_np()
기본 "기본값"에 포함되지 않는다. string.h
다음 방법을 표시:
#ifdef __USE_XOPEN2K8
/* Return a string describing the meaning of the signal number in SIG. */
extern char *strsignal (int __sig) __THROW;
# ifdef __USE_GNU
/* Return an abbreviation string for the signal number SIG. */
extern const char *sigabbrev_np (int __sig) __THROW;
/* Return a string describing the meaning of the signal number in SIG,
the result is not translated. */
extern const char *sigdescr_np (int __sig) __THROW;
# endif
__USE_GNU
을 통해 설정될 수 있다/해야 한다_GNU_SOURCE
, 컴파일 또는 파일 맨 위에.그러나 이는 모든 헤더에서 삭제된 선언과 같은 다른 모든 선언도 "활성화"한다. (헤더당 정의 해제하지 않는 한)
그래서 한 가지(또는 다른) 특수기능만 명시적으로 수입하기 위해 일단 이렇게 (복사-붙여넣기)한다."던지기"를 그만두고 "__sig"를 바꿨다.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
extern const char *sigabbrev_np(int sig) __THROW; /* __USE_GNU / _GNU_SOURCE */
#include <errno.h>
#include <elf.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
...
지금sigabbrev_np(wstate >> 8)
내게 주다TRAP
##time이 없는 등.
나는 그것을 깨닫는 데 애를 먹었다.0x57f
때문에 괜찮다는 뜻이다.5
이다TRAP
그렇지만0xb7f
그리고0x77f
이다SEGV
그리고BUS
---- 내가 어디에서 중단점을 설정하느냐에 따라, 때로는 수천 번의 지시 후에 중단점을 설정하느냐에 따라 얻게 되었다.내가 인조 포인터를 한 발짝도 물러서지 않았기 때문에...
다음 두 가지 사항에 대해 더 설명하겠다.
컴파일러가 실행 가능한 기능과 연결해야 할 기능 구현을 어떻게 알 수 있을까?이것 또한 #define을 사용하는가?
일반적인 접근법은 조건부로 하는 것이다.#define
식별자basename
의 여부에 따라 다른 이름으로_GNU_SOURCE
정의된다.예를 들어,
#ifdef _GNU_SOURCE
# define basename __basename_gnu
#else
# define basename __basename_nongnu
#endif
이제 도서관은 그 이름 아래 두 가지 행동을 모두 제공할 필요가 있다.
그렇다면, 한 기능 구현 또는 다른 기능 구현을 위해 일부 모호한 환경 변수를 정의하지 말고 사람들에게 다른 헤더를 제공하는 것이 어떨까?
종종 동일한 헤더의 내용이 다른 Unix 버전에서 약간씩 다르기 때문에, 예를 들어, 다음과 같은 용도의 단일 올바른 컨텐츠는 존재하지 않는다.<string.h>
— 많은 표준(xkcd)이 있다.여러분이 가장 좋아하는 매크로를 고를 수 있는 모든 종류의 매크로가 있다. 그래서 만약 여러분의 프로그램이 하나의 기준을 기대한다면, 도서관은 그것에 부합할 것이다.
참조URL: https://stackoverflow.com/questions/5582211/what-does-define-gnu-source-imply
'Programing' 카테고리의 다른 글
jQuery를 사용하여 Vue.js 양식에서 값 설정 (0) | 2022.04.17 |
---|---|
v-data-table을 사용 가능한 모든 공간에 수직으로 설치하는 방법 (0) | 2022.04.17 |
C와 C++의 맥락에서 활성화 기록은 무엇인가? (0) | 2022.04.17 |
$store 객체를 사용하여 Vuex 하위 모듈 내부 상태에 액세스 (0) | 2022.04.17 |
VueJS에서 애니메이션에 jQuery를 계속 사용해야 하는가? (0) | 2022.04.16 |