警告 C26427
グローバル初期化子は extern オブジェクト 'symbol' にアクセスします (i.22)
C++ Core Guidelines: I.22: グローバル オブジェクトの複雑な初期化を避ける
グローバル オブジェクトは、一貫性のない順序または未定義の順序で初期化される可能性があります。つまり、相互依存性の間にはリスクがあるため、回避する必要があります。 このガイドラインは、初期化子が extern
と見なされる別のオブジェクトを参照する場合に適用されます。
解説
オブジェクトは、次のルールに準拠している場合、extern
と見なされます。
- これは、
extern
指定子でマークされたグローバル変数であるか、クラスの静的メンバーです。 - 匿名の名前空間にない
const
としてマークされていない- 静的クラス メンバーはグローバルと見なされるため、初期化子も検査されます。
コード分析名: NO_GLOBAL_INIT_EXTERNS
例
外部バージョンチェック:
// api.cpp
int api_version = API_DEFAULT_VERSION; // Assume it can change at run time, hence non-const.
// client.cpp
extern int api_version;
bool is_legacy_mode = api_version <= API_LEGACY_VERSION; // C26427, also stale value
外部バージョンのチェックにより、信頼性が向上しました。
// api.cpp
int api_version = API_DEFAULT_VERSION; // Assume it can change at run time, hence non-const.
// client.cpp
extern int api_version;
bool is_legacy_mode() noexcept
{
return api_version <= API_LEGACY_VERSION;
}