#define에서 ##은 무엇을 의미합니까?
이 선은 무슨 뜻입니까?특히, 무엇이##
비열한?
#define Analyze(변수, 플래그) ((Something).##http) & (http:/(http)
편집:
아직도 약간 혼란스러워요.없는 결과는 무엇입니까?##
?
아직도 약간 혼란스러워요.##이 없으면 결과는 어떻게 됩니까?
보통 당신은 어떤 차이도 알아차리지 못할 것입니다.하지만 차이점이 있습니다.라고 가정합니다.Something
유형:
struct X { int x; };
X Something;
그리고 다음을 참조하십시오.
int X::*p = &X::x;
ANALYZE(x, flag)
ANALYZE(*p, flag)
토큰 연결 연산자 없음##
다음으로 확장:
#define ANALYZE(variable, flag) ((Something.variable) & (flag))
((Something. x) & (flag))
((Something. *p) & (flag)) // . and * are not concatenated to one token. syntax error!
토큰 연결을 통해 다음과 같이 확장됩니다.
#define ANALYZE(variable, flag) ((Something.##variable) & (flag))
((Something.x) & (flag))
((Something.*p) & (flag)) // .* is a newly generated token, now it works!
사전 처리기는 텍스트가 아닌 사전 처리기 토큰에서 작동합니다.따라서 두 개의 토큰을 연결하려면 명시적으로 말해야 합니다.
##
매크로 호출에서 두 개의 토큰을 연결하는 데 사용되는 토큰 연결이라고 합니다.
참조:
한 가지 매우 중요한 부분은 이 토큰 연결이 몇 가지 매우 특별한 규칙을 따른다는 것입니다.
예: IBM doc:
- 인수의 매크로가 확장되기 전에 연결이 수행됩니다.
- 연결 결과가 유효한 매크로 이름이면 일반적으로 사용할 수 없는 컨텍스트에 나타나더라도 추가로 대체할 수 있습니다.
- 매크로 정의의 대체 목록에 둘 이상의 ## 연산자 및/또는 # 연산자가 나타나면 연산자의 평가 순서가 정의되지 않습니다.
예는 또한 매우 자기 설명적입니다.
#define ArgArg(x, y) x##y
#define ArgText(x) x##TEXT
#define TextArg(x) TEXT##x
#define TextText TEXT##text
#define Jitter 1
#define bug 2
#define Jitterbug 3
출력 포함:
ArgArg(lady, bug) "ladybug"
ArgText(con) "conTEXT"
TextArg(book) "TEXTbook"
TextText "TEXTtext"
ArgArg(Jitter, bug) 3
출처는 IBM 문서입니다.다른 컴파일러에 따라 다를 수 있습니다.
라인으로:
변수 속성을 "Something"에 연결하고 논리적으로 정렬된 변수를 처리하여 Something.variable에 플래그가 설정된 경우 결과로 제공합니다.
그래서 제 마지막 의견과 당신의 질문(g++로 컴파일 가능)에 대한 예를 들어보겠습니다.
// this one fails with a compiler error
// #define ANALYZE1(variable, flag) ((Something.##variable) & (flag))
// this one will address Something.a (struct)
#define ANALYZE2(variable, flag) ((Something.variable) & (flag))
// this one will be Somethinga (global)
#define ANALYZE3(variable, flag) ((Something##variable) & (flag))
#include <iostream>
using namespace std;
struct something{
int a;
};
int Somethinga = 0;
int main()
{
something Something;
Something.a = 1;
if (ANALYZE2(a,1))
cout << "Something.a is 1" << endl;
if (!ANALYZE3(a,1))
cout << "Somethinga is 0" << endl;
return 1;
};
이는 질문에 대한 답변이 아니라 프리프로세서를 직접 탐색하는 데 도움이 되는 몇 가지 팁이 포함된 CW 게시물일 뿐입니다.
사전 처리 단계는 실제 코드가 컴파일되기 전에 실제로 수행됩니다.즉, 컴파일러가 당신의 코드를 만들기 시작하면 #define 문이나 그와 유사한 것이 남지 않습니다.
전처리기가 코드에 대해 수행하는 작업을 이해하는 좋은 방법은 전처리된 출력을 파악하여 확인하는 것입니다.
다음은 Windows용 작업 방법입니다.
test.cpp라는 간단한 파일을 만들어 폴더에 넣습니다(예: c:\temp).내 것은 다음과 같습니다.
#define dog_suffix( variable_name ) variable_name##dog
int main()
{
int dog_suffix( my_int ) = 0;
char dog_suffix( my_char ) = 'a';
return 0;
}
그다지 유용하지는 않지만, 간단합니다.Visual studio 명령 프롬프트를 열고 폴더로 이동한 후 다음 명령줄을 실행합니다.
c:\temp>cl test.cpp /P
즉, 파일과 함께 실행하는 컴파일러(cl.exe)이며 /P 옵션은 컴파일러에게 전처리된 출력을 파일에 저장하도록 지시합니다.
이제 test.cpp 옆의 폴더에 test.i가 있습니다. 이는 다음과 같습니다.
#line 1 "test.cpp"
int main()
{
int my_intdog = 0;
char my_chardog = 'a';
return 0;
}
보시다시피 #define은 남아 있지 않고 확장된 코드만 남아 있습니다.
위키백과에 따르면
토큰 붙여넣기라고도 하는 토큰 연결은 C 매크로 전처리기의 가장 미묘하고 쉽게 악용할 수 있는 기능 중 하나입니다.## 사전 처리 연산자를 사용하여 두 인수를 함께 '접착'할 수 있습니다. 이렇게 하면 두 토큰을 사전 처리된 코드에서 연결할 수 있습니다.이것은 C++ 템플릿의 조잡한 버전처럼 작동하는 정교한 매크로를 구성하는 데 사용될 수 있습니다.
토큰 연결 확인
다른 예를 살펴보겠습니다.
고려하다
#define MYMACRO(x,y) x##y
없이##
는 분히전기볼는수없습다니를 볼 수.x
그리고.y
별도의 토큰으로, 가능합니까?
예를 들어,
#define ANALYZE(variable, flag) ((Something.##variable) & (flag))
##
새 식별자를 만들지 않기 때문에 필요하지 않습니다."."을은 유효한 토큰을 .
언급URL : https://stackoverflow.com/questions/6503586/what-does-in-a-define-mean
'programing' 카테고리의 다른 글
루트 장치에서 실행 중인지 확인 (0) | 2023.07.29 |
---|---|
로드 밸런서에 클라이언트: 회의에 사용할 수 있는 서버가 없습니다. (0) | 2023.07.24 |
문서의 배열 요소를 Mongoose 삭제하고 저장 (0) | 2023.07.24 |
"NUMBER"와 "NUMBER(*,0)"는 Oracle에서 동일합니까? (0) | 2023.07.24 |
파이썬에서 호출 함수 모듈의 __name_을(를) 가져옵니다. (0) | 2023.07.24 |