Bagikan melalui


Peringatan C26426

Inisialisasi global memanggil fungsi non-constexpr 'simbol' (i.22)

Panduan Inti C++

I.22: Hindari inisialisasi kompleks objek global

Urutan eksekusi penginisialisasi untuk objek global mungkin tidak konsisten atau tidak terdefinisi, yang dapat menyebabkan masalah yang sulit direproduksi dan diselidiki. Untuk menghindari masalah tersebut, penginisialisasi global tidak boleh bergantung pada kode eksternal yang dijalankan pada waktu proses, dan itu mungkin tergantung pada data yang belum diinisialisasi. Aturan ini menandai kasus di mana objek global memanggil fungsi untuk mendapatkan nilai awalnya.

Keterangan

  • Aturan mengabaikan panggilan ke constexpr fungsi atau fungsi intrinsik pada asumsi bahwa panggilan ini akan dihitung pada waktu kompilasi atau menjamin eksekusi yang dapat diprediksi pada waktu proses.

  • Panggilan ke fungsi sebaris masih ditandai, karena pemeriksa tidak mencoba menganalisis implementasinya.

  • Aturan ini dapat berisik dalam banyak skenario umum di mana variabel jenis yang ditentukan pengguna (atau kontainer standar) diinisialisasi secara global. Ini sering karena panggilan ke konstruktor dan destruktor. Ini masih merupakan peringatan yang valid, karena menunjuk ke tempat-tempat di mana perilaku yang tidak dapat diprediksi mungkin ada atau di mana perubahan kode eksternal di masa mendatang dapat menimbulkan ketidakstabilan.

  • Anggota kelas statis dianggap global, sehingga inisialisasi mereka juga diperiksa.

Nama analisis kode: NO_GLOBAL_INIT_CALLS

Contoh

Pemeriksaan versi eksternal:

// 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

Pemeriksaan versi eksternal dibuat lebih dapat diandalkan:

// 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;
}