問題タブ [static-initialization]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - リンカがスタートアップコードを最適化しないようにするにはどうすればよいですか?
次の問題があります。私の(C ++-)プロジェクトはいくつかのサブプロジェクトで構成されています。それぞれに、起動時に実行したいコードを含むファイルがいくつかあります。これまでの私の解決策は、次のように初期化時にそれぞれのコードを呼び出す静的変数を使用することです。
サブプロジェクトごとにdllを使用してプロジェクトをビルドすると、すべてが正常に機能し、コードは期待どおりに実行されます。ただし、サブプロジェクトを静的にリンクする場合、リンカーはFoo.oに外部から参照されたコードが含まれていないと判断し、最適化します。もちろん、別の場所にsFooRegistryへの参照を追加することもできますが、これは面倒でエラーが発生しやすくなります。
これを解決するための(標準準拠の)方法は何ですか?
OK、mac/gccとwin/visual studioで何ができますか?
c++ - 静的初期化中にスレッドを安全に作成できますか?
ある時点で、main()の最初の行までスレッドを安全に作成できないことを読んだことを覚えています。これは、コンパイラが特別なコードを挿入して、静的初期化時に実行されるスレッドを機能させるためです。したがって、構築時にスレッドを作成するグローバルオブジェクトがある場合、プログラムがクラッシュする可能性があります。しかし、今は元の記事を見つけることができず、これがどれほど強い制限であるのか興味があります-それは標準によって厳密に真実ですか?ほとんどのコンパイラに当てはまりますか?それはC++0xでも当てはまりますか?標準に準拠したコンパイラが静的初期化自体をマルチスレッド化することは可能ですか?(たとえば、2つのグローバルオブジェクトが互いに接触していないことを検出し、プログラムの起動を高速化するためにそれらを別々のスレッドで初期化します)
編集:明確にするために、私は少なくとも、実装がこの点で本当に大幅に異なるかどうか、またはそれが疑似標準であるかどうかを感じ取ろうとしています。たとえば、技術的には、この標準では、さまざまなアクセス指定子(public / protected / etc。)に属するメンバーのレイアウトをシャッフルできます。しかし、私が知っているコンパイラは実際にこれを行いません。
c++ - コードで静的変数を見つける最も簡単な方法は?
アプリケーションの起動時間を占有しているライブラリの 1 つで、静的変数を見つけて書き換えるバグが私のプレートにあります。私はライブラリのコード ベースに詳しくないので、優れたヒューリスティック/テクニック/grep コマンドなどを求めています。上記の静的変数の場所を特定する際の私のタスクを容易にするでしょうか?
(PS私はすでにコードベースを検索していますstatic
;それが冗長な結果であることは言うまでもありません。)
更新: バグ レポートには、「ライブラリ XYZ は静的初期化で N ミリ秒かかる」とだけ記載されています。それ以上の静的変数に関する情報はありません。プロファイリング ログはありませんが、バグ レポーターから取得できるかどうかを確認します。
java - 静的変数の初期化?
C、C ++、Javaの静的変数がデフォルトでゼロで初期化される理由を知りたいですか?そして、なぜこれはローカル変数には当てはまらないのでしょうか?
c++ - C++ の静的初期化が同じバックトレースに 2 回現れるのは正常ですか?
起動時にフリーズする GCC でコンパイルされた C++ プログラムをデバッグしようとしています。GCC ミューテックスは関数の静的ローカル変数を保護しますが、そのようなロックを取得するのを待っていることが原因でフリーズしているようです。これがどのように起こるかはかなり混乱します。最初のモジュール A の静的初期化が発生し (GCC が呼び出す __static_init 関数がバックトレースに表示されます)、静的ローカル変数を持つ関数 Foo() が呼び出されます。静的ローカル変数は、コンストラクターが関数のいくつかのレイヤーを介して呼び出すオブジェクトであり、突然バックトレースにいくつかの ?? があり、2 番目のモジュール B の静的初期化にあります (__static 関数が何度も発生します)。 、その後 Foo() を呼び出しますが、Foo() が最初に返されなかったため、ローカル静的変数のミューテックスがまだ設定されており、ロックされています。
ある静的初期化が別の静的初期化をトリガーするにはどうすればよいですか? 私の最初の理論は共有ライブラリでした。モジュール A がモジュール B の関数を呼び出して、モジュール B をロードし、B の static init をトリガーするというものでしたが、そうではないようです。モジュール A はモジュール B をまったく使用しません。だから私は2番目の(そして恐ろしい)推測をしています。と言う:
モジュール A は、テンプレート化された関数またはテンプレート化されたクラスの関数を使用します。
foo<int>::bar()
モジュール B も使用
foo<int>::bar()
モジュール A はモジュール B にまったく依存していません
リンク時に、リンカーには の 2 つのインスタンスがありますが
foo<int>::bar()
、テンプレート関数は弱いシンボルとしてマークされているため、これは問題ありません...モジュール B はモジュール A に依存していませんが、実行時にモジュール A が を呼び出し
foo<int>::bar
、モジュール B の static init がトリガーされます。なんで?リンカーは、リンク時にモジュール A のインスタンスではなく、モジュール B の foo::bar のインスタンスを使用することを決定したためです。
この特定のシナリオは有効ですか? それとも、あるモジュールの static init が別のモジュールで static init をトリガーすることはありませんか?
明確化: GCC はミューテックスを自動的に作成して、関数の静的変数を保護します。私はミューテックスで何もしていません。これは、関数の静的変数をスレッドセーフにする GCC の方法です。
更新:静的初期化は翻訳単位間で定義されておらず、順序に依存すべきではないことを知っています。しかし、問題をデバッグする手がかりとして、これが通常の動作であるかどうかに興味があります。コンパイラがこれを行うコードを生成するのは正常ですか、それとも GCC のバグを示している可能性がありますか?
java - Java - 静的初期化ブロック内のクラス型
静的初期化ブロック内からクラス型を取得することは可能ですか?
これは私が現在持っているものの簡略化されたバージョンです::
これは、オブジェクトとその注釈などに関する情報を保持するデータ構造を初期化するという、私が行っていることに近いです...おそらく間違ったパターンを使用していますか?
編集
私の問題に最もよく当てはまるものに基づいて受け入れられた回答を選択しましたが、現在の3つの回答すべてにメリットがあるようです。
c++ - 関数ローカル静的定数オブジェクトのスレッドセーフな初期化
この質問は、私が何年も続けてきた慣習に疑問を投げかけました。
関数ローカル静的定数オブジェクトのスレッドセーフな初期化のために、オブジェクトの実際の構築を保護しますが、それを参照する関数ローカル参照の初期化は保護しません。このようなもの:
ロックには時間がかかるという考え方であり、参照が複数のスレッドによって上書きされても問題ありません。
これがあれば興味があります
- 実際には十分安全ですか?
- ルールに従って安全ですか?(私は知っています、現在の標準は「並行性」が何であるかさえ知りませんが、すでに初期化された参照を踏みにじることはどうですか?そしてPOSIXのような他の標準はこれに関連する何かを言いますか?)
これを知りたいのは、コードをそのままにしておくことができるのか、それとも戻って修正する必要があるのかを知りたいからです。
探究心のために:
私が使用したそのような関数ローカル静的constオブジェクトの多くは、最初の使用時にconst配列から初期化され、ルックアップに使用されるマップです。たとえば、タグ名の文字列がenum
値にマップされるXMLパーサーがいくつかあるので、後でswitch
タグのenum
値を上書きできます。
代わりに何をすべきかについていくつかの答えを得ましたが、実際の質問に対する答えが得られなかったので(上記の1.と2を参照)、これについて報奨金を開始します。繰り返しますが、私は代わり
に何ができるかに興味がありません。私はこれについて本当に知りたいです。
java - JLSには、静的初期化ブロックの実行順序に関する保証はありますか?
次のような構造を使用するのは信頼できるのだろうか。
初期化するブロックの前に初期化ブロックが実行されるNullPointerException
ため、取得する可能性はありますか?msgSource
engMessages
msgSource
(上部の初期化ブロックの最後で初期化を行わない理由について:好みの問題です。説明されている構造が信頼できない場合は、そうします)
c++ - デストラクタに副作用があり、オブジェクトが別の静的オブジェクトのデストラクタからアクセスされる場合、静的な初期化解除を行う方法は?
C++ FAQ Lite のセクション 10.13 で説明されている、静的初期化の大失敗を回避するための単純でよく知られたパターンがあります。
この標準パターンでは、構築されたオブジェクトが破棄されない (デストラクタに重要な副作用がない場合は問題にならない) か、別の静的オブジェクトのデストラクタから静的オブジェクトに安全にアクセスできないというトレードオフがあります。 ( C++ FAQ Lite のセクション 10.14 を参照してください)。
私の質問は次のとおりです。静的オブジェクトのデストラクタに最終的に発生する必要がある重要な副作用があり、静的オブジェクトに別の静的オブジェクトのデストラクタからアクセスする必要がある場合、静的初期化解除の大失敗をどのように回避しますか?
(注: FAQ-lite は、この質問はC++ FAQs: FAQ 16.17 で回答されていると言及しています: M. Cline および G. Lomow によるよくある質問です。私はこの本にアクセスできないため、代わりにこの質問をします。 )
c++ - 静的初期化中にコードが実行されているかどうかを検出する C/C++ の方法はありますか?
DLL として利用できるトレース ライブラリを作成しています。システム内の基本的にすべてのコンポーネントで消費されます。注意が必要な要件の 1 つは、トレース関数をプロセスの有効期間の非常に早い段階 (main() が実行される前であっても) に呼び出す必要があることです。
このライブラリのコンシューマーには、実行可能ファイル、静的にリンクされた DLL、遅延ロードされた DLL、および動的にロードされた DLL が含まれます。すべてのバリエーション。
一部のトレース機能は、静的初期化ではうまく機能しませんが、他の機能は問題ありません。理想的には、初期化時に最小限の安全な機能を消費者に提供し、初期化が完了した後に完全な機能を提供できるようにしたいと考えています。
特定のコンシューマーは DLL 自体であり、それらをホストする実行可能ファイルを制御できないため、コンシューマーに明示的な "I'm done init" 呼び出しを行うように依頼しても機能しません。同じ問題がチェーンを 1 レベル上に移動するだけです。
私が望んでいるのは、現在静的初期化で実行しているかどうか、またはその段階が完了しているかどうかをランタイムに問い合わせる方法があることです。そのようなことは可能ですか?
さらに複雑なことに、5 つのプラットフォームで実行する必要があります。一度だけのソリューションは必要ありませんが、すべてのプラットフォームで何らかの形で機能させる必要があります。