programing

## 및 __LINE__를 사용하여 C 매크로 생성(위치 지정 매크로와의 토큰 연결)

goodsources 2022. 7. 10. 21:25
반응형

## 및 __LINE__를 사용하여 C 매크로 생성(위치 지정 매크로와의 토큰 연결)

회선번호에 따라 이름을 붙여 함수를 만드는 C 매크로를 만들고 싶습니다.다음과 같은 작업을 할 수 있을 것 같았습니다(실제 함수는 괄호 안에 문장이 있습니다).

#define UNIQUE static void Unique_##__LINE__(void) {}

내가 바라던 건 다음과 같은 것들이었어

static void Unique_23(void) {}

안 되네.토큰 연결에서는 포지셔닝 매크로가 문자 그대로 처리되어 다음과 같이 확장됩니다.

static void Unique___LINE__(void) {}

이게 가능한가요?

문제는 매크로 치환이 있는 경우 스트링라이징 연산자 중 하나가 아닌 경우 프리프로세서는 매크로를 재귀적으로만 확장한다는 것입니다.#토큰 붙여넣기 연산자도 없습니다.##적용됩니다.따라서 간접 레이어를 몇 개 더 사용해야 합니다.또한 토큰 붙여넣기 연산자를 재귀적으로 확장된 인수와 함께 사용할 수 있습니다.

#define TOKENPASTE(x, y) x ## y
#define TOKENPASTE2(x, y) TOKENPASTE(x, y)
#define UNIQUE static void TOKENPASTE2(Unique_, __LINE__)(void) {}

그리고나서,__LINE__확장 중에 라인 번호까지 확장됩니다.UNIQUE(어느 쪽과도 관련이 없기 때문에)#또는##토큰 페이스트(pasting)TOKENPASTE.

또, 다음의 기능도 있는 것에 주의할 필요가 있습니다.__COUNTER__매크로는 평가될 때마다 새로운 정수로 확장되며, 예를 들어 여러 인스턴스가 필요한 경우UNIQUE같은 행에 매크로를 표시합니다.주의:__COUNTER__는 MS Visual Studio, GCC(V4.3 이후) 및 Clang에서 지원되지만 표준 C는 아닙니다.

GCC는 결과를 '문자열화'할 필요가 없는 한 '포장'(또는 실현)할 필요가 없습니다.GCC는 기능을 가지고 있지만 ALL은 플레인 C 버전1로 실행할 수 있습니다(버클리 4.3C가 너무 빨라서 사용법을 배울 가치가 있다고 주장하는 사람도 있습니다).

**Clang(llvm)은 매크로 확장을 위한 화이트 스페이스를 올바르게 제공하지 않습니다.- 공백이 추가됩니다(이것에 의해, C의 프리프로세서가 수십년간에 걸쳐 # 또는 *매크로 확장을 실시하지 않습니다).대표적인 예는 X11 컴파일입니다.매크로 「Concat3」가 파손되어 있습니다.그 결과, MISNAMEED C Identifier가 되어 있습니다.이것은 당연히 빌드할 수 없습니다.조립에 실패하는 게 그들의 직업이에요

여기서의 답은 "표준을 어기는 새로운 C는 나쁜 C"입니다.이 해커들은 항상 아무 이유 없이 디폴트를 변경하지만 실제로는 "C"를 개선하지 않습니다(단, C는 아직 아무도 책임을 지지 않고 있는 이유를 설명하기 위해 만든 장치입니다).


이전 C 프리프로세서가 UNIq_()__를 지원하지 않는 것은 문제가 되지 않습니다.이는 #pragma를 지원했기 때문입니다.#pragma는 "코드의 컴파일러 브랜드 해킹을 해킹으로 플래그가 붙는 것"을 가능하게 하며, 표준에 영향을 주지 않고도 기능합니다.기본값을 변경하는 것은 쓸모없는 일이며, t를 사용하는 동안 함수가 하는 것과 같습니다.내 생각에 그는... 말웨어인 것 같다.

언급URL : https://stackoverflow.com/questions/1597007/creating-c-macro-with-and-line-token-concatenation-with-positioning-macr

반응형