C ++ 20: İşlevsellik testi makro ile derleyicinin işlevlerini belirleyin

Adanali

Active member
C ++ 20: İşlevsellik testi makro ile derleyicinin işlevlerini belirleyin


  1. C ++ 20: İşlevsellik testi makro ile derleyicinin işlevlerini belirleyin

C ++ 20, işlevsellik testlerinin makresini getirir, bu nedenle desteklediği özelliklerin kullandığı derleyiciyi inceler.








En son C ++ özelliklerini denerseniz, genellikle hata mesajları alırsınız. Şimdi soru ortaya çıkıyor: Bundan kim sorumlu?

  1. Yalnız bir hata yaptın mı?
  2. Derleyici bu işlevi kullandı mı?
  3. Bir derleyici hata oluştu mu?






Rainer Grimm yıllardır yazılım mimarı, ekip ve eğitim müdürü olarak çalıştı. C ++ programlama dilleri, Python ve Haskell hakkında makaleler yazmayı seviyor, ancak uzman konferanslarla konuşmayı da seviyor. Modern C ++ blogunda, C ++ tutkusuyla yoğun bir şekilde ilgileniyor.







Seçenek 3 nadiren oluşur, bu yüzden sadece bir soruyu cevaplamanız gerekir: derleyici bu işlevi destekliyor mu?

Bu sorunun cpprerereeanice ve işlevsellik testlerinin makresi sayesinde cevaplaması kolaydır.

C ++ derleyici desteği


CppReference.com/compiler_support, C ++ 26'ya kadar C ++ 11 standartları da dahil olmak üzere temel dil ve kütüphane hakkında sorulara cevap verir.

Aşağıdaki tablolar, ana dil desteğine ve C ++ 26 standardı için kütüphaneye genel bir bakış sağlar.

C ++ 26 Çekirdek Dil









C ++ 26 Kütüphane









Cevaplar yeterince spesifik değilse, C ++ 20'de işlevsellik testlerinin makresi yardımcı olur.

İşlevsellik testlerinin makro


Başlık ile <version> Derleyiciden C ++ 11 veya daha yüksek desteğini isteyebilirsiniz. Ana dil veya kütüphanenin özellikleri, özellikleri sorabilirsiniz. <version> İşlev uygulandığında bir sayıya genişleyen 300'den fazla makro tanımlamıştır. Sayı, C ++ standart tasarım işlevinin eklendiği yıl ve ay içindir. Bunlar sayıları static_assert, Lambdas VE Concepts.


__cpp_static_assert 200410L&#13;
__cpp_lambdas 200907L&#13;
__cpp_concepts 201907L


İşlev Testi Makro Makro, tüm makroları listeler.

CPPReference tarafından benimsenen ve uyarladığım aşağıdaki program, ana dil C ++ 20'nin tüm makrolarını gösteriyor. Bayrak /Zc:__cplusplus Windows altındaki makro işlevsellik testini etkinleştirin.


// featureTesting20.cpp&#13;
// from cppreference.com&#13;
&#13;
#if __cplusplus < 201100&#13;
# error "C++11 or better is required"&#13;
#endif&#13;
&#13;
#include <algorithm>&#13;
#include <cstring>&#13;
#include <iomanip>&#13;
#include <iostream>&#13;
#include <string>&#13;
&#13;
#ifdef __has_include&#13;
# if __has_include(<version>)&#13;
# include <version>&#13;
# endif&#13;
#endif&#13;
&#13;
#define COMPILER_FEATURE_VALUE(value) #value&#13;
#define COMPILER_FEATURE_ENTRY(name) { #name, COMPILER_FEATURE_VALUE(name) },&#13;
&#13;
#ifdef __has_cpp_attribute&#13;
# define COMPILER_ATTRIBUTE_VALUE_AS_STRING(s) #s&#13;
# define COMPILER_ATTRIBUTE_AS_NUMBER(x) COMPILER_ATTRIBUTE_VALUE_AS_STRING(x)&#13;
# define COMPILER_ATTRIBUTE_ENTRY(attr) &#13;
{ #attr, COMPILER_ATTRIBUTE_AS_NUMBER(__has_cpp_attribute(attr)) },&#13;
#else&#13;
# define COMPILER_ATTRIBUTE_ENTRY(attr) { #attr, "_" },&#13;
#endif&#13;
&#13;
// Change these options to print out only necessary info.&#13;
static struct PrintOptions {&#13;
constexpr static bool titles = 1;&#13;
constexpr static bool attributes = 1;&#13;
constexpr static bool general_features = 1;&#13;
constexpr static bool core_features = 1;&#13;
constexpr static bool lib_features = 1;&#13;
constexpr static bool supported_features = 1;&#13;
constexpr static bool unsupported_features = 1;&#13;
constexpr static bool sorted_by_value = 0;&#13;
constexpr static bool cxx11 = 1;&#13;
constexpr static bool cxx14 = 1;&#13;
constexpr static bool cxx17 = 1;&#13;
constexpr static bool cxx20 = 1;&#13;
constexpr static bool cxx23 = 0;&#13;
} print;&#13;
&#13;
struct CompilerFeature {&#13;
CompilerFeature(const char* name = nullptr, const char* value = nullptr)&#13;
: name(name), value(value) {}&#13;
const char* name; const char* value;&#13;
};&#13;
&#13;
static CompilerFeature cxx20[] = {&#13;
COMPILER_FEATURE_ENTRY(__cpp_aggregate_paren_init)&#13;
COMPILER_FEATURE_ENTRY(__cpp_char8_t)&#13;
COMPILER_FEATURE_ENTRY(__cpp_concepts)&#13;
COMPILER_FEATURE_ENTRY(__cpp_conditional_explicit)&#13;
COMPILER_FEATURE_ENTRY(__cpp_consteval)&#13;
COMPILER_FEATURE_ENTRY(__cpp_constexpr)&#13;
COMPILER_FEATURE_ENTRY(__cpp_constexpr_dynamic_alloc)&#13;
COMPILER_FEATURE_ENTRY(__cpp_constexpr_in_decltype)&#13;
COMPILER_FEATURE_ENTRY(__cpp_constinit)&#13;
COMPILER_FEATURE_ENTRY(__cpp_deduction_guides)&#13;
COMPILER_FEATURE_ENTRY(__cpp_designated_initializers)&#13;
COMPILER_FEATURE_ENTRY(__cpp_generic_lambdas)&#13;
COMPILER_FEATURE_ENTRY(__cpp_impl_coroutine)&#13;
COMPILER_FEATURE_ENTRY(__cpp_impl_destroying_delete)&#13;
COMPILER_FEATURE_ENTRY(__cpp_impl_three_way_comparison)&#13;
COMPILER_FEATURE_ENTRY(__cpp_init_captures)&#13;
COMPILER_FEATURE_ENTRY(__cpp_modules)&#13;
COMPILER_FEATURE_ENTRY(__cpp_nontype_template_args)&#13;
COMPILER_FEATURE_ENTRY(__cpp_using_enum)&#13;
};&#13;
&#13;
&#13;
constexpr bool is_feature_supported(const CompilerFeature& x) {&#13;
return x.value[0] != '_' && x.value[0] != '0' ;&#13;
}&#13;
&#13;
inline void print_compiler_feature(const CompilerFeature& x) {&#13;
constexpr static int max_name_length = 44; //< Update if necessary&#13;
std::string value{ is_feature_supported(x) ? x.value : "------" };&#13;
if (value.back() == 'L') value.pop_back(); //~ 201603L -> 201603&#13;
// value.insert(4, 1, '-'); //~ 201603 -> 2016-03&#13;
if ( (print.supported_features && is_feature_supported(x))&#13;
|| (print.unsupported_features && !is_feature_supported(x))) {&#13;
std::cout << std::left << std::setw(max_name_length)&#13;
<< x.name << " " << value << 'n';&#13;
}&#13;
}&#13;
&#13;
template<size_t N>&#13;
inline void show(char const* title, CompilerFeature (&features)[N]) {&#13;
if (print.titles) {&#13;
std::cout << 'n' << std::left << title << 'n';&#13;
}&#13;
if (print.sorted_by_value) {&#13;
std::sort(std::begin(features), std::end(features),&#13;
[](CompilerFeature const& lhs, CompilerFeature const& rhs) {&#13;
return std::strcmp(lhs.value, rhs.value) < 0;&#13;
});&#13;
}&#13;
for (const CompilerFeature& x : features) {&#13;
print_compiler_feature(x);&#13;
}&#13;
}&#13;
&#13;
int main() {&#13;
&#13;
if (print.cxx20 && print.core_features) show("C++20 CORE", cxx20);&#13;
&#13;
}


Aşağıdaki derleyici Explorer ekran görüntüleri, GCC derleyicisinin 8.1, 10.1 ve 14.1'in C ++ 20 desteğini göstermektedir.




















Sırada ne var?


Bir sonraki makalemde C ++ 23'teki yolculuğuma devam ediyorum.


(RME)
 
Üst