Rumah > Artikel > pembangunan bahagian belakang > Mengapakah pengembangan makro variadik MSVC berbeza daripada GCC, dan bagaimanakah kita boleh mengatasi percanggahan ini?
Peluasan Makro Variadik MSVC
Makro variadik menawarkan keupayaan pengembangan serba boleh, membolehkan anda mengendalikan berbilang argumen dalam makro. Dalam GCC, makro seperti berikut berfungsi seperti yang dijangkakan:
<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>
Gelagat Pengembangan MSVC
Walau bagaimanapun, dalam Microsoft's C Compiler (MSVC ), pengembangan makro berkelakuan berbeza . Daripada mengembangkan setiap hujah secara berasingan, MSVC menggabungkan semua hujah menjadi satu ungkapan.
struct MyStructure<br>{<br> void Foo()<br> {</p> <pre class="brush:php;toolbar:false">EXPAND_THESE(Property1, Property2, Property3, Property4)
}
Asas * ibu bapa;
};
Peluasan GCC:
{
batal Foo()
{
parent->GetProperty<Property1>(); parent->GetProperty<Property2>(); parent->GetProperty<Property3>(); parent->GetProperty<Property4>();
}
Asas * ibu bapa;
}
MSVC Peluasan:
{
void Foo()
{
parent->GetProperty<Property1, Property2, Property3, Property4>();
}
Asas * ibu bapa;
}
Penyelesaian:
Jeff Walden mencadangkan penyelesaian menggunakan corak berikut:
<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>
Pendekatan ini memerlukan penentuan makro CHOOSE_HELPER untuk setiap kiraan makro variadik yang dikehendaki (cth., ERROR1, ERROR2, dll.). Walau bagaimanapun, adalah penting untuk mengisytiharkan setiap makro CHOOSE_HELPER dalam skop definisi makro variadic.
Penyelesaian yang lebih ringkas dan mudah alih adalah dengan memanfaatkan teknik berikut:
<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>
Dengan persediaan ini , makro boleh ditakrifkan sebagai:
<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>
Dengan menggunakan OVERLOAD_MACRO hierarki, adalah mungkin untuk mengelak daripada menentukan makro CHOOSE_HELPER.
Atas ialah kandungan terperinci Mengapakah pengembangan makro variadik MSVC berbeza daripada GCC, dan bagaimanakah kita boleh mengatasi percanggahan ini?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!