9

今日、私は、おそらくそれほど重要ではないが、それでも私を困惑させる特殊性に遭遇した。たぶん、私も C++ を正しく理解していないだけです。

ソース ファイル内の一部の配列は、次のように文字列リテラルを指します。

const char* a[] = { "a", "b", "c" };
const char* b[] = { "d", "e"};
const char* c[] = { "f", "g"};

これらのポインター配列は、ライブラリーから関数ポインターを取得するために渡される以外の方法で使用されることはありませんGetProcAddress(これは、非ブロッキング動的 OpenAL/EFX/capture 関数ローダーおよびコンテキスト クリエーター/マネージャーです)。

static const最終的に、これらの変数は .cpp ファイルの外部では必要ないため、これらの変数を宣言する必要があるのではないかと思いました。そのため、内部リンケージを明示的にすることが適切に思えました。いずれにせよ内部リンケージが必要なので (ISO14882 3.5(3))、コンパイラーが既に想定していることを明示することによってのみ、善良な市民になることができます。

その無害な変更を行うと、実行可能ファイルのサイズが 512 バイト増加しました。追加の 512b は実際には問題ではありませんが、まったく同じことが別のコードになるということは意味がないように思えました。非推奨 (ISO14882 7.3.1.1(2)) であるためstatic const、匿名の名前空間も試しましたが、同じ結果が得られました。

アセンブラー ソースを見ると、明示的な内部リンケージ (staticまたはnamespace{}) によって文字列リテラルが.rdataではなくに移動され、文字.data列リテラルは、すべての文字列とすべてのポインターを 1 つのブロックに含める代わりに、文字列リテラルへのポインター配列でインターリーブされることがわかります。それぞれ。ここにもおそらく異なるサイズの理由があります.1つのセクションから別のセクションへのデータのシャッフルがセクションサイズの制約に達した可能性が非常に高いです. 興味深いことに、3 つのフレーバーはすべて名前の付け方も異なります。

今、私は疑問に思っています:私は誤りを犯していますか?それらのポインターは内部リンケージを持っていないはずですか?

また、私の理解constでは、すでに読み取り専用ですが、どこまでstatic const「読み取り専用」ですか(一方は入り.rdata、もう一方は入りません)?

4

1 に答える 1

7

配列は宣言されていないconstため、暗黙的に内部リンケージでもありません。あなたが持っているのは、constへのポインタの非const配列です。

.rdataとはいえ、これが文字列がまたはで終わるかどうかに影響する理由はわかりません.data

于 2011-06-30T14:34:36.960 に答える