Rumah > pembangunan bahagian belakang > C++ > Mengapakah pengembangan makro variadik MSVC berbeza daripada GCC, dan bagaimanakah kita boleh mengatasi percanggahan ini?

Mengapakah pengembangan makro variadik MSVC berbeza daripada GCC, dan bagaimanakah kita boleh mengatasi percanggahan ini?

Barbara Streisand
Lepaskan: 2024-11-06 09:10:02
asal
948 orang telah melayarinya

Why does MSVC   variadic macro expansion differ from GCC, and how can we overcome this discrepancy?

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>
Salin selepas log masuk

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>
<div class="code" style="position:relative; padding:0px; margin:0px;"><pre class="brush:php;toolbar:false">EXPAND_THESE(Property1, Property2, Property3, Property4)
Salin selepas log masuk

}

Asas * ibu bapa;
};

Peluasan GCC:

struct MyStructure
{
batal Foo()
{

parent->GetProperty<Property1>(); 
parent->GetProperty<Property2>(); 
parent->GetProperty<Property3>(); 
parent->GetProperty<Property4>();
Salin selepas log masuk

}

Asas * ibu bapa;
}

MSVC Peluasan:

struktur MyStructure
{
void Foo()
{

parent->GetProperty<Property1, Property2, Property3, Property4>();
Salin selepas log masuk

}

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>
Salin selepas log masuk

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>
Salin selepas log masuk

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>
Salin selepas log masuk

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!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Artikel terbaru oleh pengarang
Cadangan popular
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan