다음은 새 버전의 컴파일러로 업그레이드 할 때 발생한 문제입니다.
토큰 붙여 넣기 연산자 ( ##
)를 불필요하게 사용하면 이식이 불가능하며 원하지 않는 공백, 경고 또는 오류가 발생할 수 있습니다.
토큰 붙여 넣기 연산자의 결과가 유효한 전 처리기 토큰이 아닌 경우 토큰 붙여 넣기 연산자는 불필요하고 해로울 수 있습니다.
예를 들어, 토큰 붙여 넣기 연산자를 사용하여 컴파일 타임에 문자열 리터럴을 빌드하려고 할 수 있습니다.
#define STRINGIFY(x) #x
#define PLUS(a, b) STRINGIFY(a##+##b)
#define NS(a, b) STRINGIFY(a##::##b)
printf("%s %s\n", PLUS(1,2), NS(std,vector));
일부 컴파일러에서는 예상되는 결과가 출력됩니다.
1+2 std::vector
다른 컴파일러에서는 원하지 않는 공백이 포함됩니다.
1 + 2 std :: vector
상당히 최신 버전의 GCC (> = 3.3 정도)는이 코드를 컴파일하지 못합니다.
foo.cpp:16:1: pasting "1" and "+" does not give a valid preprocessing token
foo.cpp:16:1: pasting "+" and "2" does not give a valid preprocessing token
foo.cpp:16:1: pasting "std" and "::" does not give a valid preprocessing token
foo.cpp:16:1: pasting "::" and "vector" does not give a valid preprocessing token
해결책은 전 처리기 토큰을 C / C ++ 연산자에 연결할 때 토큰 붙여 넣기 연산자를 생략하는 것입니다.
#define STRINGIFY(x) #x
#define PLUS(a, b) STRINGIFY(a+b)
#define NS(a, b) STRINGIFY(a::b)
printf("%s %s\n", PLUS(1,2), NS(std,vector));
연결에 대한 GCC CPP 문서 장 에는 토큰 붙여 넣기 연산자에 대한 더 유용한 정보가 있습니다.
std::wstring BuildDate = WIDEN(__DATE__) L" " WIDEN(__TIME__);
전체 문자열을 한 번에 암시 적으로 빌드 할 수 있습니다 .