MSVC Variadic 매크로 확장
Variadic 매크로는 다양한 확장 기능을 제공하므로 매크로 내에서 여러 인수를 처리할 수 있습니다. GCC에서는 다음과 같은 매크로가 예상대로 작동합니다.
<code class="cpp">#define VA_NARGS_IMPL(_1, _2, _3, _4, _5, N, ...) N #define VA_NARGS(...) VA_NARGS_IMPL(__VA_ARGS__, 5, 4, 3, 2, 1) #define FULLY_EXPANDED(count, ...) \ MAC ## count (__VA_ARGS__) #define SEMI_EXPANDED(count, ...) FULLY_EXPANDED(count, __VA_ARGS__) #define EXPAND_THESE(...) SEMI_EXPANDED(VA_NARGS(__VA_ARGS__), __VA_ARGS__) #define ACTUAL_MACRO(x) parent->GetProperty<x>(); #define MAC1(a) ACTUAL_MACRO(a) #define MAC2(a,b) MAC1(a) ACTUAL_MACRO(b) #define MAC3(a,b,c) MAC2(a,b) ACTUAL_MACRO(c) #define MAC4(a,b,c,d) MAC3(a,b,c) ACTUAL_MACRO(d) #define MAC5(a,b,c,d,e) MAC4(a,b,c,d) ACTUAL_MACRO(e)</code>
MSVC 확장 동작
그러나 Microsoft의 C 컴파일러(MSVC)에서는 매크로 확장이 다르게 동작합니다. . 각 인수를 개별적으로 확장하는 대신 MSVC는 모든 인수를 단일 표현식으로 연결합니다.
struct MyStructure<br>{<br> void Foo()<br> {</p> <pre class="brush:php;toolbar:false">EXPAND_THESE(Property1, Property2, Property3, Property4)
}
기본 * 상위;
};
GCC 확장:
{<br> void Foo()<br> {</p><pre class="brush:php;toolbar:false">parent->GetProperty<Property1>(); parent->GetProperty<Property2>(); parent->GetProperty<Property3>(); parent->GetProperty<Property4>();</p> <p>}</p> <p>Base * parent;<br>}<br>
MSVC 확장:
struct MyStructure<br>{<br> void Foo()<br> {</p> <pre class="brush:php;toolbar:false">parent->GetProperty<Property1, Property2, Property3, Property4>();
}
Base * parent;
}
해결책:
Jeff Walden은 다음을 사용하여 해결 방법을 제안했습니다. 다음 패턴:
<code class="cpp">#define ERRORn(...) ERROR_CHOOSE_HELPERn(COUNT_ARGS_MAX5(__VA_ARGS__), __VA_ARGS__) #define ERROR_CHOOSE_HELPER1(count) ERROR1 #define ERROR_CHOOSE_HELPER2(count) ERROR2 #define ERROR_CHOOSE_HELPER(count) ERROR_CHOOSE_HELPER##count</code>
이 접근 방식을 사용하려면 원하는 각 가변 매크로 수(예: ERROR1, ERROR2 등)에 대해 CHOOSE_HELPER 매크로를 정의해야 합니다. 그러나 가변 매크로 정의 범위 내에서 각 CHOOSE_HELPER 매크로를 선언하는 것이 중요합니다.
더 간결하고 이식 가능한 솔루션은 다음 기술을 활용하는 것입니다.
<code class="cpp">#define GLUE(x, y) x y #define RETURN_ARG_COUNT(_1_, _2_, _3_, _4_, _5_, count, ...) count #define EXPAND_ARGS(args) RETURN_ARG_COUNT args #define COUNT_ARGS_MAX5(...) EXPAND_ARGS((__VA_ARGS__, 5, 4, 3, 2, 1, 0)) #define OVERLOAD_MACRO2(name, count) name##count #define OVERLOAD_MACRO1(name, count) OVERLOAD_MACRO2(name, count) #define OVERLOAD_MACRO(name, count) OVERLOAD_MACRO1(name, count) #define CALL_OVERLOAD(name, ...) GLUE(OVERLOAD_MACRO(name, COUNT_ARGS_MAX5(__VA_ARGS__)), (__VA_ARGS__))</code>
이 설정을 사용하면 , 매크로는 다음과 같이 정의할 수 있습니다.
<code class="cpp">#define ERROR1(title) printf("Error: %s\n", title) #define ERROR2(title, message)\ ERROR1(title);\ printf("Message: %s\n", message) #define ERROR(...) CALL_OVERLOAD(ERROR, __VA_ARGS__) #define ASSERT1(expr) singleArgumentExpansion(expr) #define ASSERT2(expr, explain) twoArgumentExpansion(expr, explain) #define ASSERT(...) CALL_OVERLOAD(ASSERT, __VA_ARGS__)</code>
OVERLOAD_MACRO 계층 구조를 사용하면 CHOOSE_HELPER 매크로 정의를 피할 수 있습니다.
위 내용은 MSVC 가변 매크로 확장이 GCC와 다른 이유는 무엇이며 이러한 불일치를 어떻게 극복할 수 있습니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!