GCCが静的変数(すでに自分の関数内に存在する変数)を容易にするために使用する内部(隠れた?)変数を識別することによって、関数が初めて呼び出されたかどうかを確認する方法はありますか?既存の静的変数を使用して最初の呼び出しを識別しますか?
私はこれらの変数をC++コードから取得したいと考えています。
GCCが静的変数(すでに自分の関数内に存在する変数)を容易にするために使用する内部(隠れた?)変数を識別することによって、関数が初めて呼び出されたかどうかを確認する方法はありますか?既存の静的変数を使用して最初の呼び出しを識別しますか?
私はこれらの変数をC++コードから取得したいと考えています。
GCCは、変数が初期化されているかどうかを示す隠しフラグを使用しています。これにアクセスする方法はありません。それでも、これらは実際には「最初の時間」を追跡するのではなく、変数が初期化されているかどうかを追跡します。次のことを考慮してください:
void func()
{
static T a;
static T b;
}
しかし、標準では実際には異なるスレッドによって初期化されます。だから、もしそれが最初に起こったのであれば。少なくとも最適化されていないモードでは、それぞれ独自のロックで処理されているようですが、gccの逆アセンブリをチェックすると、コードが最適化モードで多く変更されます(したがって、初回は明確に定義されていません)。
また、マーク氏のコメントでは、初期化が行われたときにどのタイプを使用しているかによって大きく異なることが指摘されています。シンプルな型は保証されていなくても、グローバルに初期化される場合もあれば、関数が最初に呼び出されるまで待つこともあります。
どうして最初の入力を知る必要があるのですか?
コンパイラの内部に頼る方法はありません。試しても、次のバージョンでは変更されないという保証はありません。
使用この共通のイディオム:
static bool firsttime = true;
if (firsttime)
{
firsttime = false;
// other stuff here
}
それは確かに良いイディオムであり、何か他のことをしようとする人は誰でも、狂った亡命者に送られるべきです。それにもかかわらず、私はGCCで何をしたいのですか? – Mikhail
@Misha、単純なPOD型はコンパイル時に初期化され、実行時のサポートは必要ありません。コンストラクタを必要とする静的変数、または実行時の値で初期化されるコードは、コード行が実行されるときに初期化されますが、gccがどのようなメカニズムを使用するのかはわかりません。私が答えて言うように、gccはあらゆるリリースのメカニズムを自由に変更できるので、それを理解しようとするのは本当に狂っています。 –
スレッドセーフティに関しては、複数の呼び出し元が最初のブロックに終わる可能性があるので、これは良い慣用法ではありません。 –