34

私は常に、GCCがELFまたはそのようなファイルのセグメント(または最適化のためのセグメント)にstatic const変数を配置すると信じていました。しかし、そうではないようです。.rodata.text

私は現在gcc (GCC) 4.7.0 20120505 (prerelease)、GNU/Linuxを搭載したラップトップで使用しています。そして、静的定数変数を.bssセグメントに配置します。

/*
 * this is a.c, and in its generated asm file a.s, the following line gives:
 *   .comm a,4,4 
 * which would place variable a in .bss but not .rodata(or .text)
 */
static const int a;

int main()
{
    int *p = (int*)&a;
    *p = 0;  /* since a is in .data, write access to that region */
             /* won't trigger an exception */
    return 0;
}

それで、これはバグですか、それとも機能ですか?これをbugzillaのバグとして提出することにしましたが、最初に助けを求める方がよいかもしれません。

GCCがconst変数を配置できない理由はあります.rodataか?

更新しました:

テストされたように、明示的な初期化(のような)を持つ定数変数はGCCによってconst int a = 0;配置されますが、変数は初期化されません。.rodataしたがって、この質問は後で閉じられる可能性があります-私はおそらく正しい質問を提示しませんでした。

また、前の言葉で、変数aが「.data」セクションに配置されていると書きましたが、これは正しくありません。初期化されていないため、実際には.bssセクションに配置されます。上記のテキストが修正されました。

4

4 に答える 4

12

コンパイラはそれを共通にしました。これは他の互換性のあるシンボルとマージでき、明示的に初期化された定義がない場合は bss に入れることができます (ディスク上のスペースを取りません)。それをrodataに入れることはトレードオフになります。実行時にメモリを節約 (コミット チャージ) しますが、ディスク上のスペースをより多く使用します (巨大な配列の場合、多くの可能性があります)。

むしろrodataに入れたい場合は、-fno-commonGCCのオプションを使用してください。

于 2012-05-30T15:53:32.773 に答える
3

修飾されていると宣言されたオブジェクトへの書き込みは、const未定義の動作です。

C では、オブジェクト自体が変更不可であることを宣言する方法はありません。オブジェクトへの特定のアクセスによって変更可能であることを禁止するだけです。ここには があるint*ので、コンパイラが診断を発行することを強制されないという意味で、変更は「許可」されています。Cでキャストを行うということは、自分が何をしているのかを知っていると仮定することを意味します。

于 2012-05-30T15:08:02.757 に答える
1

GCC が const 変数を .rodata に配置できない理由はありますか?

プログラムはコンパイラーによって最適化されます (-O0一部の最適化が行われている場合でも)。一定の伝播が行われます: http://en.wikipedia.org/wiki/Constant_folding

次のようにコンパイラをだますようにしてください (このプログラムはまだ技術的に未定義の動作であることに注意してください)。

#include <stdio.h>

static const int a;

int main(void)
{
    *(int *) &a = printf("");  // compiler cannot assume it is 0

    printf("%d\n", a);

    return 0;
}
于 2012-05-30T15:19:12.497 に答える