問題タブ [static-order-fiasco]
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++ の静的初期化順序の問題を見つける
静的な初期化順序 fiascoでいくつかの問題に遭遇しました。発生する可能性のあるものを見つけるために、大量のコードをくまなく調べる方法を探しています。これを効率的に行う方法について何か提案はありますか?
編集:静的な初期化順序の問題を解決する方法についていくつかの良い答えを得ていますが、それは私の質問ではありません。この問題の対象となるオブジェクトを見つける方法を知りたいです。この点に関しては、Evan の回答がこれまでのところ最良のようです。valgrind を使用できるとは思いませんが、同様の機能を実行できるメモリ分析ツールがあるかもしれません。これは、特定のビルドの初期化順序が間違っていて、ビルドごとに順序が変わる可能性がある場合にのみ問題をキャッチします。おそらく、これをキャッチする静的分析ツールがあるでしょう。私たちのプラットフォームは、AIX 上で動作する IBM XLC/C++ コンパイラーです。
c++ - C++ 静的初期化順序
C++ で静的変数を使用する場合、ある変数を初期化して別の変数をそのコンストラクターに渡したいと思うことがよくあります。つまり、相互に依存する静的インスタンスを作成したいと考えています。
単一の .cpp または .h ファイル内では、これは問題ではありません。インスタンスは、宣言された順序で作成されます。ただし、静的インスタンスを別のコンパイル単位のインスタンスで初期化したい場合、順序を指定することは不可能のようです。その結果、天候によっては、別のインスタンスに依存するインスタンスが構築され、その後でのみ別のインスタンスが構築されることがあります。その結果、最初のインスタンスが正しく初期化されません。
静的オブジェクトが正しい順序で作成されるようにする方法を知っている人はいますか? 私は長い間解決策を探し、それらすべて (Schwarz Counter ソリューションを含む) を試してきましたが、本当に機能するものがあるとは思えません。
1 つの可能性は、静的関数メンバーを使用したトリックです。
確かに、これは機能します。残念ながら、globalObject.MemberFunction() の代わりに globalObject().MemberFunction() を記述する必要があるため、クライアント コードがやや混乱し、洗練されていません。
更新:ご反応ありがとうございます。残念ながら、私は自分の質問に答えたようです。私はそれと一緒に暮らすことを学ばなければならないと思います...
c++ - Initializing qt resources embedded in static library
I have next situation: I need to create widget in standalone static library, which then will be linked with final application (visual c++ 9.0, qt 4.5). This static widget library contains some resources (icons), and consist of a several .cpp files (each contains standalone widget). As far as I know, i must initialize qt resource system, if i use them (resources) in static library, with call to "Q_INIT_RESOURCE( resource_file_name )". I solved this with next code (in every .cpp file in static library):
Instead of my first approach, I have created separate init.cpp file in static library project with initialization code (to avoid including initialization code in every .cpp file), but this didn't work.
Why this didn't work ?
Is this approach with StaticLibInitializer is safe and portable among various compilers and platforms ?
c++ - C ++で静的初期化順序の大失敗を再現する
アプリケーションのクラッシュに関連する C++ での静的初期化順序の大失敗について読みました。理解できたと思いますが、いくつか質問があります:
1) この問題を再現したい場合、どうすれば (プログラムがクラッシュするように) 再現できますか? クラッシュを再現するテストプログラムを書きたいと思います。可能であればソースコードを提供していただけますか?2) このC++ FAQ Lite
の記事
を読みましたが、2 つの異なるファイルに x と y の 2 つの静的オブジェクトがあり、y が x のメソッドを呼び出すと書かれています。グローバルな静的メンバーがファイル レベルのスコープを持っているため、どのように可能でしょうか?
3) この問題は非常に危険です。コンパイラ レベルで修正する試みはありますか?
4) あなたの C++ エキスパートは、実際のプロダクションでこの問題に何回直面しましたか?
c++ - 静的初期化順序の大失敗
私は本からSIOFについて読んでいて、それは例を与えました:
今私の質問は:
上記のコードでは、次のことが起こりますか?
- file1.cppのコンパイル中、コンパイラはyをそのままにします。つまり、ストレージを割り当てません。
- コンパイラはxにストレージを割り当てますが、初期化しません。
- file2.cppをコンパイルしている間、コンパイラはxをそのままにします。つまり、ストレージを割り当てません。
- コンパイラはyにストレージを割り当てますが、初期化はしません。
- file1.oとfile2.oをリンクするときに、file2.oを最初に初期化するようにします。したがって、
xは初期値0を取得しますか?または初期化されませんか?
c++ - 静的初期化順序の大失敗
彼の「ThinkinginC++」(第10章)で、Eckelは、大失敗を解決するためにJerrySchwarzによって開拓された手法について説明しています。xを100に、yを200に初期化し、それらをすべての変換ユニット間で共有する場合は、次のようなInitializer.hを作成すると彼は言います。
そして、実装ファイルには
そしてEckelは、「(実装ファイル内の)静的初期化はこれらすべての値を強制的にゼロにする」と述べています。
次の場合を考えてみましょう。コンパイラは、そのヘッダーが含まれている他のファイルの後に実装ファイルを処理します(つまり、他のファイルでxとyがすでに100と200に設定されていることを意味します)。コンパイラはを認識int x
しますが、それは何をしますか?xとyをゼロに設定して、初期化と以前のファイルで発生する可能性のあるすべての変更を排除しますか?しかし、そうであれば、それinitCount
もゼロに設定され、テクニック全体が分解されます。
c++ - C++ ライブラリでの静的 STL コンテナーの二重初期化
ここには「静的初期化順序の大失敗」に関するいくつかの良い質問と回答がありますが、クラッシュはしないがデータを失い、リークするため、特に醜い、さらに別の表現にぶつかったようです。
カスタム C++ ライブラリと、それに対してリンクするアプリケーションがあります。ライブラリには、クラスのすべてのインスタンスを登録する静的 STL コンテナーがあります。これらのインスタンスは、たまたまアプリケーションの静的変数です。
「大失敗」の結果 (私は信じています)、アプリケーションの初期化中にコンテナーがアプリケーション インスタンスでいっぱいになり、ライブラリが初期化され、コンテナーがリセットされ (おそらくメモリ リーク)、図書館。
これは、単純化されたコードで再現した方法です。
mylib.hpp:
mylib.cpp:
myapp.cpp:
オブジェクトを次のようにコンパイルします。
myapp1 を実行します。
myapp2 を実行します。
静的ベクトルが再初期化されたのか、それとも初期化前に使用されたのかという質問があります。これは予期される動作ですか?
ライブラリを 'mylib.a' (ar rcs mylib.a mylib.o) として 'ar' すると、問題は発生しませんが、.a にリンクするための有効な順序が 1 つしかなく、それが原因である可能性があります。ライブラリは最後に、myapp1 はここにあります。
しかし、私たちの実際のアプリケーションでは、多くのオブジェクト ファイルといくつかの静的 (.a) ライブラリがいくつかの静的レジストリを共有する、より複雑なアプリケーションで問題が発生しており、これまでに解決できた唯一の方法は、'[10.15 ] 「静的な初期化順序の大失敗」を防ぐにはどうすればよいですか?' .
(正しくリンクしているかどうかを確認するために、多少複雑なビルド システムを調査中です)。
c++ - Nifty / Schwarzカウンター、標準に準拠していますか?
今朝、同僚と静的変数の初期化順序について話し合いました。彼はNifty/Schwarzカウンターについて言及しましたが、私は(一種の)困惑しています。私はそれがどのように機能するかを理解していますが、これが技術的に言えば、標準に準拠しているかどうかはわかりません。
次の3つのファイルを想定します(最初の2つはMore C ++ Idiomsからコピーパスタされています)。
...そしてここに問題があります!2つの静的変数があります。
Stream.cpp
;の"nifty_counter" と- の「初期化子」
Program.cpp
。
2つの変数はたまたま2つの異なるコンパイル単位にあるため、のコンストラクターが呼び出される前に0に初期化される(AFAIK)公式保証はありません。nifty_counter
initializer
私は2つの簡単な解決策を、これが「機能する」理由の2つと考えることができます。
- 最新のコンパイラは、2つの変数間の依存関係を解決し、実行可能ファイル内でコードを適切な順序で配置するのに十分なほど賢いです(ほとんどありません)。
nifty_counter
記事にあるように、実際には「ロード時」に初期化され、その値は実行可能ファイルの「データセグメント」にすでに配置されているため、常に「コードが実行される前」に初期化されます(可能性が高い)。
これらは両方とも、非公式でありながら可能な実装に依存しているように私には思えます。この標準は準拠していますか、それとも「機能する可能性が非常に高い」ので、心配する必要はありませんか?
c++ - このコードは未定義の動作を生成しますか、それとも単に未指定の動作ですか?
次のように、2 つのコンパイル ユニットがあるとします。
VC2010で試してみると、初期化value1
さvalue2
れて最初にゼロになります。両方ともvalue1
動的value2
に初期化されておらず、デフォルトの初期化は適用されませんか?
ありがとう、
java - Javaには静的な順序初期化の大失敗がありますか?
ここでの最近の質問には、同期なしでシングルトンを実装するための次のコード(まあ、これに似ています)がありました。
今、私はこれが何をしているのか理解していると思います。インスタンスはstatic final
であるため、スレッドが呼び出されるずっと前にビルドされgetInstance()
、同期の実際の必要はありません。
getInstance()
同期が必要になるのは、2つのスレッドが同時に呼び出そうとした場合のみです(そして、そのメソッドは、"static final"
時間ではなく最初の呼び出しで構築を行いました)。
したがって、私の質問は基本的に次のとおりです。なぜ、次のようなシングルトンの怠惰な構築を好むのでしょうか。
私の唯一の考えは、このstatic final
メソッドを使用すると、C++の静的初期化順序の大失敗のようにシーケンスの問題が発生する可能性があるということでした。
まず、Javaには実際にこの問題がありますか?クラス内の順序が完全に指定されていることは知っていますが、クラス間で一貫した順序が保証されていますか(クラスローダーなど)?
第二に、順序が一貫している場合、なぜ怠惰な構築オプションが有利になるのでしょうか?