Aracılığıyla paylaş


C++ içindeki öznitelikler

C++ Standardı ortak bir öznitelik kümesini tanımlar. Ayrıca, derleyici satıcılarının satıcıya özgü bir ad alanında kendi özniteliklerini tanımlamasına da olanak tanır. Ancak, derleyiciler yalnızca standartta tanımlanan öznitelikleri tanımak için gereklidir.

Bazı durumlarda, standart öznitelikler derleyiciye özgü __declspec parametrelerle çakışıyor. Microsoft C++'da özniteliğini [[deprecated]] kullanmak __declspec(deprecated)yerine kullanabilirsiniz. [[deprecated]] özniteliği, uyumlu herhangi bir derleyici tarafından tanınır. ve dllexportgibi dllimport diğer __declspec tüm parametreler için şu ana kadar öznitelik eşdeğeri yoktur, bu nedenle söz dizimlerini kullanmaya __declspec devam etmeniz gerekir. Öznitelikler tür sistemini etkilemez ve bir programın anlamını değiştirmez. Derleyiciler tanımadıkları öznitelik değerlerini yoksayar.

Visual Studio 2017 sürüm 15.3 ve üzeri (ve üzeri ile /std:c++17 kullanılabilir): Öznitelik listesi kapsamında, tek using bir tanıtıcıya sahip tüm adlar için ad alanını belirtebilirsiniz:

void g() {
    [[using rpr: kernel, target(cpu,gpu)]] // equivalent to [[ rpr::kernel, rpr::target(cpu,gpu) ]]
    do task();
}

C++ standart öznitelikleri

C++11'de öznitelikler, C++ yapılarına (sınıflar, işlevler, değişkenler ve bloklar dahil ancak bunlarla sınırlı olmamak üzere) ek bilgilerle açıklama eklemek için standartlaştırılmış bir yol sağlar. Öznitelikler satıcıya özgü olabilir veya olmayabilir. Derleyici, bu bilgileri bilgi iletileri oluşturmak veya öznitelikli kodu derlerken özel mantık uygulamak için kullanabilir. Derleyici tanımadığı öznitelikleri yoksayar; bu da bu söz dizimini kullanarak kendi özel özniteliklerinizi tanımlayamamanızı sağlar. Öznitelikler çift köşeli ayraç içine alınır:

[[deprecated]]
void Foo(int);

Öznitelikler, __declspec() yönergeler (Visual C++) veya __attribute__ (GNU) gibi #pragma satıcıya özgü uzantılara standartlaştırılmış bir alternatifi temsil eder. Ancak çoğu amaç için satıcıya özgü yapıları kullanmanız gerekir. Standart şu anda uyumlu bir derleyicinin tanıması gereken aşağıdaki öznitelikleri belirtir.

[[carries_dependency]]

[[carries_dependency]] özniteliği, işlevin iş parçacığı eşitlemesi için veri bağımlılığı sıralamasını yaydığını belirtir. Özniteliği, geçirilen bağımsız değişkenin işlev gövdesine bir bağımlılık taşıdığını belirtmek için bir veya daha fazla parametreye uygulanabilir. Dönüş değerinin işlev dışında bir bağımlılık taşıdığını belirtmek için özniteliği işlevin kendisine uygulanabilir. Derleyici, daha verimli kod oluşturmak için bu bilgileri kullanabilir.

[[deprecated]]

Visual Studio 2015 ve üzeri:[[deprecated]] özniteliği, bir işlevin kullanım için tasarlanmamış olduğunu belirtir. Veya bir kitaplık arabiriminin gelecek sürümlerinde mevcut olmayabilir. [[deprecated]] özniteliği bir sınıfın bildirimine, tür tanımı-adı, değişken, statik olmayan veri üyesi, işlev, ad alanı, numaralandırma, numaralandırıcı veya şablon özelleştirmesine uygulanabilir. derleyici, istemci kodu işlevi çağırmaya çalıştığında bilgilendirme iletisi oluşturmak için bu özniteliği kullanabilir. Microsoft C++ derleyicisi bir [[deprecated]] öğenin kullanımını algıladığında, derleyici uyarısı C4996'yı tetikler.

[[fallthrough]]

Visual Studio 2017 ve üzeri: (ve sonraki sürümlerle /std:c++17 kullanılabilir.) özniteliği, [[fallthrough]] deyimler bağlamında switch , derleyiciye (veya kodu okuyan herkese) fallthrough davranışının amaçlandığına ilişkin bir ipucu olarak kullanılabilir. Microsoft C++ derleyicisi şu anda fallthrough davranışı konusunda uyarı vermediğinden bu özniteliğin derleyici davranışı üzerinde hiçbir etkisi yoktur.

[[likely]]

Visual Studio 2019 sürüm 16.6 ve üzeri: (Ve sonraki sürümlerle /std:c++20 kullanılabilir.) özniteliği, [[likely]] derleyiciye, öznitelikli etiket veya deyimin kod yolunun alternatiflerden daha büyük olasılıkla yürütüldüğünü belirten bir ipucu belirtir. Microsoft derleyicisinde özniteliği blokları [[likely]] "sık erişimli kod" olarak işaretler ve bu da iç iyileştirme puanını artırır. Hız için iyileştirme yapılırken puan daha fazla artırılır ve boyut iyileştirildiğinde bu kadar artırılmaz. Net puan, inlining, loop unrolling ve vectorizing optimizations olasılığını etkiler. ve'nin [[likely]][[unlikely]] etkisi Profil destekli iyileştirmeye benzer, ancak geçerli çeviri birimi kapsamında sınırlıdır. Bu öznitelik için blok yeniden sıralama iyileştirmesi henüz uygulanmadı.

[[maybe_unused]]

Visual Studio 2017 sürüm 15.3 ve üzeri: (Ve sonraki sürümlerle /std:c++17 kullanılabilir.) [[maybe_unused]] özniteliği değişken, işlev, sınıf, tür tanımı, statik olmayan veri üyesi, sabit listesi veya şablon özelleştirmesinin kasıtlı olarak kullanılamayabileceğini belirtir. İşaretlenen [[maybe_unused]] bir varlık kullanılmadığında derleyici uyarı vermez. Özniteliği olmadan bildirilen bir varlık daha sonra özniteliğiyle yeniden oluşturulabilir ve bunun tersi de geçerlidir. Bir varlık, işaretlenen ilk bildirimi çözümlendikten sonra ve geçerli çeviri biriminin geri kalanı için işaretlenmiş[[maybe_unused]] olarak kabul edilir.

[[nodiscard]]

Visual Studio 2017 sürüm 15.3 ve üzeri: (Ve sonraki sürümlerle /std:c++17 kullanılabilir.) İşlevin dönüş değerinin atılmak üzere tasarlanmamış olduğunu belirtir. Bu örnekte gösterildiği gibi C4834 uyarılarını yükseltir:

[[nodiscard]]
int foo(int i) { return i * i; }

int main()
{
    foo(42); //warning C4834: discarding return value of function with 'nodiscard' attribute
    return 0;
}

[[noreturn]]

[[noreturn]] özniteliği, bir işlevin hiçbir zaman döndürülmeyeceğini belirtir; başka bir deyişle, her zaman bir özel durum oluşturur veya çıkar. Derleyici, varlıklar için [[noreturn]] derleme kurallarını ayarlayabilir.

[[unlikely]]

Visual Studio 2019 sürüm 16.6 ve üzeri: (Ve sonraki sürümlerle /std:c++20 kullanılabilir.) özniteliği, [[unlikely]] derleyiciye, öznitelikli etiket veya deyimin kod yolunun alternatiflere göre daha az yürütüldüğünü belirten bir ipucu belirtir. Microsoft derleyicisinde özniteliği blokları [[unlikely]] "soğuk kod" olarak işaretler ve bu da iç iyileştirme puanını geriler. Puan, boyut için iyileştirme yapılırken daha fazla azalmış olur ve hız için iyileştirme yaparken bu kadar azalmış olmaz. Net puan, inlining, loop unrolling ve vectorizing optimizations olasılığını etkiler. Bu öznitelik için blok yeniden sıralama iyileştirmesi henüz uygulanmadı.

Microsoft'a özgü öznitelikler

[[gsl::suppress(rules)]]

Microsoft'a özgü [[gsl::suppress(rules)]] özniteliği, kodda Yönergeler Destek Kitaplığı (GSL) kurallarını zorunlu kılan denetleyicilerden gelen uyarıları engellemek için kullanılır. Örneğin, şu kod parçacığını göz önünde bulundurun:

int main()
{
    int arr[10]; // GSL warning C26494 will be fired
    int* p = arr; // GSL warning C26485 will be fired
    [[gsl::suppress(bounds.1)]] // This attribute suppresses Bounds rule #1
    {
        int* q = p + 1; // GSL warning C26481 suppressed
        p = q--; // GSL warning C26481 suppressed
    }
}

Örnek şu uyarıları tetikler:

  • C26494 (Tür Kuralı 5: Her zaman bir nesneyi başlatın.)

  • C26485 (Sınır Kuralı 3: İşaretçi bozunması için dizi yok.)

  • C26481 (Sınır Kuralı 1: İşaretçi aritmetiği kullanmayın. Bunun yerine span kullanın.)

Bu kodu CppCoreCheck kod çözümleme aracı yüklü ve etkinleştirilmiş olarak derlediğinizde ilk iki uyarı tetiklenir. Ancak üçüncü uyarı özniteliği nedeniyle tetiklenmiyor. Belirli bir kural numarası eklemeden yazarak [[gsl::suppress(bounds)]] sınır profilinin tamamını gizleyebilirsiniz. C++ Temel Yönergeleri, daha iyi ve daha güvenli kod yazmanıza yardımcı olmak için tasarlanmıştır. suppress özniteliği, istenmeyen uyarıları kapatmayı kolaylaştırır.

[[msvc::flatten]]

Microsoft'a [[msvc::forceinline_calls]]özgü özniteliği [[msvc::flatten]] ile çok benzerdir ve aynı yerlerde ve aynı şekilde kullanılabilir. Aradaki fark, [[msvc::flatten]][[msvc::forceinline_calls]] hiçbir çağrı kalmayıncaya kadar özyinelemeli olarak uygulandığı kapsamdaki tüm çağrıların olmasıdır. Bu, işlevin sonuçta elde edilen kod boyutu büyümesi veya derleyicinin aktarım hızı için sonuçları olabilir ve bunu el ile yönetmeniz gerekir.

[[msvc::forceinline]]

Bir işlev bildiriminden önce yerleştirildiğinde, Microsoft'a özgü özniteliği [[msvc::forceinline]] ile aynı anlama __forceinlinegelir.

[[msvc::forceinline_calls]]

Microsoft'a özgü öznitelik [[msvc::forceinline_calls]] bir deyimine veya bloğuna yerleştirilebilir. Satır içi buluşsal öğesinin bu deyimdeki veya bloktaki tüm çağrıları denemesine [[msvc::forceinline]] neden olur:

void f() {
    [[msvc::forceinline_calls]]
    {
        foo();
        bar();
    }
    ...
    [[msvc::forceinline_calls]]
    bar();
    
    foo();
}

'a fooyapılan ilk çağrı ve her iki çağrı barda bildiriliyor __forceinlinegibi değerlendirilir. İkinci çağrısı foo olarak __forceinlinedeğerlendirilmez.

[[msvc::intrinsic]]

özniteliğinin [[msvc::intrinsic]] uygulandığı işlevde üç kısıtlaması vardır:

  • İşlev özyinelemeli olamaz; gövdesinde yalnızca parametre türünden dönüş türüne kadar olan bir static_cast return deyimi olmalıdır.
  • işlevi yalnızca tek bir parametreyi kabul edebilir.
  • Derleyici /permissive- seçeneği gereklidir. /std:c++20(Ve sonraki seçenekler varsayılan olarak geçerlidir/permissive-.)

Microsoft'a özgü [[msvc::intrinsic]] öznitelik, derleyiciye parametre türünden dönüş türüne adlandırılmış atama işlevi gören bir meta işlevi satır içi olarak belirtmesini söyler. Öznitelik bir işlev tanımında mevcut olduğunda, derleyici bu işleve yapılan tüm çağrıları basit bir atamayla değiştirir. [[msvc::intrinsic]] Özniteliği Visual Studio 2022 sürüm 17.5 önizleme 2 ve sonraki sürümlerde kullanılabilir. Bu öznitelik yalnızca onu izleyen belirli işlev için geçerlidir.

Örnek

Bu örnek kodda [[msvc::intrinsic]] , işlevine my_move uygulanan öznitelik, derleyicinin işlevine çağrıları gövdesindeki yerleşik statik atamayla değiştirmesini sağlar:

template <typename T>
[[msvc::intrinsic]] T&& my_move(T&& t) { return static_cast<T&&>(t); }

void f() {
    int i = 0;
    i = my_move(i);
}

[[msvc::noinline]]

Bir işlev bildiriminden önce yerleştirildiğinde, Microsoft'a özgü özniteliği [[msvc::noinline]] ile aynı anlama declspec(noinline)gelir.

[[msvc::noinline_calls]]

Microsoft'a özgü özniteliği [[msvc::noinline_calls]] ile aynı kullanıma [[msvc::forceinline_calls]]sahiptir. Herhangi bir deyimin veya bloğun önüne yerleştirilebilir. Bu bloktaki tüm çağrıları zorlamak yerine, uygulandığı kapsam için inlining'i kapatma etkisine sahiptir.

[[msvc::no_tls_guard]]

Microsoft'a özgü [[msvc::no_tls_guard]] öznitelik, DLL'lerdeki iş parçacığı yerel değişkenlerine ilk erişimde başlatma denetimlerini devre dışı bırakır. Denetimler, Visual Studio 2019 sürüm 16.5 ve sonraki sürümleri kullanılarak oluşturulan kodda varsayılan olarak etkinleştirilir. Bu öznitelik yalnızca onu izleyen belirli değişken için geçerlidir. Denetimleri genel olarak devre dışı bırakmak için derleyici seçeneğini kullanın /Zc:tlsGuards- .