静的オブジェクトの初期化について学習しようとしています。静的初期化は、定数式とconstexpr
. 動的な初期化はかなり難しいようです。
[basic.start.init]/4
メインの最初のステートメントの前に、静的記憶域期間を持つ非ローカル変数の動的初期化が行われるかどうかは、実装によって定義されます。初期化が main の最初のステートメントの後のある時点まで延期される場合、初期化される変数と同じ変換単位で定義された関数または変数の最初の odr-use (3.2) の前に発生するものとします。
脚注 34
副作用のある初期化を持つ静的ストレージ期間を持つ非ローカル変数は、odr で使用されていなくても初期化する必要があります (3.2、3.7.1)。
[basic.start.init]/5
スレッドの初期関数の最初のステートメントの前に、静的またはスレッド記憶期間を持つ非ローカル変数の動的初期化が行われるかどうかは、実装によって定義されます。初期化がスレッドの初期関数の最初のステートメントの後のある時点まで延期される場合、変数と同じ変換単位で定義されたスレッド記憶期間を持つ変数の最初の ODR 使用 (3.2) の前に発生するものとします。初期化する。
「スレッドの初期関数」は、std::thread で開始されたスレッドだけでなく、main を参照していると思います。
h1.h
#ifndef H1_H_
#define H1_H_
extern int count;
#endif
tu1.cpp
#include "h1.h"
struct S
{
S()
{
++count;
}
};
S s;
tu2.cpp
#include "h1.h"
int main(int argc, char *argv[])
{
return count;
}
tu3.cpp
#include "h1.h"
int count;
したがって、コンパイラが動的な初期化を延期する場合、脚注 34 は、s
ある時点で初期化する必要があると述べているようです。翻訳単位には動的な初期化を行う変数が他にないため、tu1 の変数の初期化を強制するために odr-use を使用する変数は他にありません。どの時点で初期化されたことがs
保証されますか?
main は 1 を返すことが保証されていますか? また、1 を返すことが保証されないように、このプログラムを変更する方法はありますか? または、保証されていない場合、保証されるようにこのプログラムを変更する方法はありますか?
s
の定義がとは異なる翻訳単位になるように、コードを分割しましたmain
。これにより、main
odr が使用されているかどうかという問題が回避されます。s
それが翻訳単位の唯一のオブジェクトであることを考えると、それはmain
1 を返すことが保証されていますか?