Aracılığıyla paylaş


Uyarı C26426

Genel başlatıcı constexpr olmayan bir işlevi 'symbol' olarak çağırır (i.22)

C++ Temel Yönergeleri

I.22: Genel nesnelerin karmaşık bir şekilde başlatılmasından kaçının

Genel nesneler için başlatıcıların yürütülmesinin sırası tutarsız veya tanımsız olabilir, bu da yeniden üretilmesi ve araştırılması zor sorunlara yol açabilir. Bu tür sorunları önlemek için, genel başlatıcıların çalışma zamanında yürütülen dış koda bağımlı olmaması ve henüz başlatılmamış verilere bağımlı olması gerekir. Bu kural, genel nesnelerin ilk değerlerini almak için işlevleri çağırdığı durumları işaretler.

Açıklamalar

  • Kural, bu çağrıların derleme zamanında hesaplanacağı veya çalışma zamanında tahmin edilebilir yürütmeyi garanti edeceği varsayımı üzerine işlevlere veya iç işlevlere yapılan çağrıları constexpr yoksayar.

  • Denetleyici uygulamalarını analiz etmeye çalışmadığından satır içi işlevlere yapılan çağrılar hala bayraklı olarak işaretlenir.

  • Bu kural, kullanıcı tanımlı türdeki bir değişkenin (veya standart kapsayıcının) genel olarak başlatıldığı birçok yaygın senaryoda gürültülü olabilir. Bunun nedeni genellikle oluşturuculara ve yıkıcılara yapılan çağrılardır. Tahmin edilemeyen davranışların mevcut olabileceği veya dış kodda gelecekteki değişikliklerin kararlılık oluşturabileceği yerlere işaret ettiğinden, bu hala geçerli bir uyarıdır.

  • Statik sınıf üyeleri genel olarak kabul edilir, bu nedenle başlatıcıları da denetlenür.

Kod analizi adı: NO_GLOBAL_INIT_CALLS

Örnekler

Dış sürüm denetimi:

// api.cpp
int api_version = API_DEFAULT_VERSION; // Assume it can change at run time, hence non-const.
int get_api_version() noexcept {
    return api_version;
}

// client.cpp
int get_api_version() noexcept;
bool is_legacy_mode = get_api_version() <= API_LEGACY_VERSION; // C26426, also stale value

Dış sürüm denetimi daha güvenilir hale getirildi:

// api.cpp
int& api_version() noexcept {
    static auto value = API_DEFAULT_VERSION;
    return value;
}
int get_api_version() noexcept {
    return api_version();
}

// client.cpp
int get_api_version() noexcept;
bool is_legacy_mode() noexcept {
    return get_api_version() <= API_LEGACY_VERSION;
}