web-dev-qa-db-ja.com

void * p = && abc;での&&の意味

コードvoid *p = &&abc;に出くわしました。ここでの&&の意味は何ですか?右辺値の参照については知っていますが、このコンテキストで使用される&&は異なると思います。 &&void *p = &&abc;で何を示していますか?

102
Brent Arias

&&はgccの拡張子です 現在の関数で定義されているラベルのアドレスを取得します。

void *p = &&abcは標準のC99およびC++では違法です。

This g ++でコンパイルします。

154
Prasoon Saurav

それを見つける方法

これはラベルのアドレスであり、 [〜#〜] gcc [〜#〜] に固有の機能です。

int main(void) {
    void* startp;
s:
    startp = &&s;
    printf("the assignment above starts at address %p\n", startp);
    return 0;
}

テストすることで、自分でそれを理解できたはずです。

int main(void) {
    void* startp;
    int a;
    startp = &&a;
    printf("startp=%p\n", startp);
    return 0;
}

その場合、GCCは次のように述べています。

エラー:ラベル「a」は使用されていますが、定義されていません

ボンネットの下-アセンブリ

これを本当に理解するにはアセンブラを知っている必要がありますが、ラベルのアドレスが何を意味するのかを説明しようと思います。

OSがディスクから.exeファイルをロードした後、「ローダー」と呼ばれるオペレーティングシステムのコンポーネント(Windowsには「PEローダー」があり、Linuxには「ELFローダー」があります。コンパイルされている場合は他のコンポーネントもあります)。カーネル)、それはそのプログラムの「仮想化」を行い、それをプロセスに変えます。

このプロセスは、それがRAMで唯一のものであり、RAM(つまり、32ビットマシンでは0x00000000-0xFFFFFFFF)全体にアクセスできる)と見なします。 。

(上記は起こっていることのほんの少しの概要です、あなたはそれを完全に理解するために本当にアセンブリを学ぶ必要があるので、私に耐えてください)

現在、ソースコードのラベルは基本的にアドレスです。 「gotolabel;」そのアドレスへのジャンプ以外は何もしません(アセンブリ内の 命令ポインタ について考えてください)。このラベルには、このRAMアドレスが格納されています。これにより、そのアドレスを見つけることができます。

ASMを学習すると、そのアドレスが実行可能ファイルの.textセクション内の命令を指していることがわかります。 .textセクションは、実行するプログラムの(バイナリ)コードを保持するセクションです。

これは次の方法で調べることができます。

objdump -x a.out

実用例

[〜#〜] gcc [〜#〜] で説明されているように、これを使用してジャンプテーブルを初期化できます。一部の スキャナージェネレーター のように re2c-gパラメーターを参照)は、これを使用してよりコンパクトなスキャナーを生成します。たぶん、同じ手法を採用している パーサジェネレータ もあります。

96
Flavius