#define 매크로에서 # 기호를 이스케이프 처리하시나요?
-
16-09-2019 - |
문제
피투성이의 세부 사항을 다루지 않고 #define
다음으로 확장되는 매크로 #include
하지만 '#' 기호는 전처리기를 혼란스럽게 합니다(인수를 인용하고 싶다고 생각하기 때문입니다).
예를 들어, 저는 다음과 같은 작업을 하고 싶습니다:
#define MACRO(name) #include "name##foo"
그리고 다음과 같이 사용하세요:
MACRO(Test)
다음으로 확장됩니다.
#include "Testfoo"
겸손한 # 기호로 인해 전처리기가 소리를 냅니다.MinGW에서 다음과 같은 오류가 발생했습니다.
'#' is not followed by a macro parameter
# 기호를 피해야 할 것 같지만 이것이 가능하다면 그렇지 않습니다.
예, 매크로는 정말 악합니다...
해결책
내가 기억하는 한, 당신은 정의에서 다른 사전 처리기 지침을 사용할 수 없다.
다른 팁
그것 ~이다 해시 토큰을 전처리 토큰 스트림에 삽입 할 수 있습니다. 다음과 같이 할 수 있습니다.
#define MACRO(hash, name) hash include name
MACRO(#,"hello")
- expands to :
# include "hello"
하지만, 표준은 전처리 지침의 존재에 대한 그러한 라인에 대한 추가 분석을 명시 적으로 배제합니다 [CPP.Rescan] :
결과적으로 완전히 거시적 인 사전 처리 토큰 시퀀스는 유사하더라도 전처리 지침으로 처리되지 않습니다.
문제는 실제로 전처리기의 출력에 # 기호가 표시되지 않는다는 것입니다.
분명히 당신은 매크로 확장의 일부로 새로 생성된 #include 지시어를 처리하기 위해 전처리기가 파일을 다시 분석하기를 원합니다.그런 식으로 작동하지 않습니다.행이 #으로 시작하면 전처리기에 대한 명령이고 해석됩니다.행이 #으로 시작하지 않으면 매크로 대체를 포함한 전처리기 변환만 적용됩니다.이것은 한 줄에 한 번만 수행되는 테스트입니다.
MACRO(Test)
#으로 시작하지 않습니다.따라서 전처리기 지시문으로 해석되지 않습니다.대신 매크로 교체 규칙이 적용됩니다.
#은 매크로에서 사용될 때 특별한 의미가 있기 때문입니다.
# means quote the following token (which should be a macro parameter name)
## means concatenate the preceding and following tokens.
귀하의 상황에서 #은 적절한 토큰이 뒤 따릅니다. 따라서 귀하의 상황에서 우리는 수준의 간접을 거쳐야합니다.
#define QUOTE(name) #name
#define TEST(name) QUOTE(name ## foo)
#include TEST(scot)
당신은 그렇게 할 수 없습니다. 사전 처리기 지침은 거시적 확장 전에 인식됩니다. 매크로가 사전 처리기 지침처럼 보이는 것으로 확장되면 해당 지침은 인식되지 않습니다. 당신이 할 수있는 최선은 파일 이름에 대한 매크로를 만드는 것입니다.
#define MACRO(name) "name##foo"
...
#include MACRO(Test)
이것 ~할 것 같다 작업 (정기적으로 작동합니다 #define
매개 변수가없는 매크로이지만 매개 변수가있는 매크로로 테스트하지 않았습니다).
#define MACRO(name) <name##foo>
#include MACRO(Test)
#define HASH_SIGN #
BOOST_PP_CAT(HASH_SIGN, include)
#define PARAM_NAME Param
#define GETNAME_(a) #a
#define GETNAME(a) GETNAME_(a)
int Param;
printf("%s = %i\n", GETNAME(PARAM_NAME), PARAM_NAME);