4

C++ 標準セクション 3.6.2 パラグラフ 3 は、非ローカル オブジェクトの動的初期化が main() の最初のステートメントの後に発生するかどうかは実装定義であると述べています。

これの理論的根拠と、この方法で非ローカルオブジェクトの初期化を延期するコンパイラを知っている人はいますか? 私は、main() に入る前にこれらの初期化を実行する g++ に最も精通しています。

この質問は関連しています:静的変数の動的初期化フェーズ しかし、私は具体的にどのコンパイラがこのように動作することが知られているかを尋ねています。

この段落の唯一の根拠は、実行時にロードされる動的ライブラリをサポートすることかもしれませんが、標準が動的ロードの問題を考慮しているとは思いません。

4

2 に答える 2

0

理由の 1 つとして、次のことが考えられます。

static char data[1000000000000000000000000000000];

void main(int argc)
{
    if (argc > 0)
        data[0] = 0;
}

本当に必要であることが判明した場合にのみ、この静的配列を割り当てて初期化するのが合理的かもしれません。いくつかのアプリケーションが同様のものに出くわし、委員会を納得させるのに十分な発言力を持っていた可能性があります. C# での私自身の経験では、クラスを jit した直後にクラスの静的メンバーが割り当てられない状況に遭遇しました。それらは、最初の使用時に 1 つずつ割り当てられました。その場合、それを行う正当な理由はまったくありませんでした。それは単なる災害でした。多分彼らは今これを修正しました。

他の理由も考えられます。

于 2012-06-22T23:04:01.147 に答える
0

C++11 ドラフトから:

メインの最初のステートメントの前に、静的記憶域期間を持つ非ローカル変数の動的初期化が行われるかどうかは、実装によって定義されます。初期化が main の最初のステートメントの後のある時点まで延期される場合、初期化される変数と同じ変換単位で定義された関数または変数の最初の odr-use (3.2) の前に発生するものとします。[鉱山を強調]

つまり、同じ翻訳単位で定義されたものを使用する前に、静的変数を初期化する必要があります。

dlopen動的ライブラリ(DLLまたはSO)を遅延して、または動的に(呼び出しなどで)ロードおよび初期化できるようにするために、この方法が行われているように見えますLoadLibrary。DLL 自体が読み込まれる前に、DLL で定義された変数を初期化できないことは明らかです。

当然のことながら、C++ は DLL について何も知らないため、標準では直接言及されていません。しかし、委員会の人々は実際の環境とコンパイラについて知っており、DLL についても確かに知っています。この句がないと、DLL の遅延読み込みは技術的に C++ 仕様に違反します。(実装者がそれを行うのを妨げるというわけではありませんが、私たち全員がお互いに協力しようとする方が良いです。)

そして、どのシステムがこれをサポートしているかについては、少なくとも MS Visual C++ コンパイラは遅延動的リンクをサポートしています (DLL は最初に使用するまでロードされません)。また、最新のプラットフォームのほとんどは、DLL の動的ロードをサポートしています。

于 2012-06-23T00:56:02.117 に答える