void * a =&aはどのように合法ですか?


88

次のC ++コードを考えてみます。

void* a = &a;

宣言されていない識別子を使用するとコンパイラが文句を言わないのはなぜですか?

また、コンパイラは変数aを何と見なしていますか?それはvoidオブジェクトへのvoid*ポインターですか、それともポインターへのポインターですか?




15
なぜこれを実行するのかを言及する必要があります-スタックのトップへのポインタを取得します(そこからあらゆる種類のものをいじることができます)。
OrangeDog 2013

回答:


95

C ++での変数の宣言のスコープは、かなり驚くべきものです。

void* a =               &a;
         ^~~~~~~~~~~~~~~~~
          a declared as `void*` from here on

したがって、&aisですvoid**が、どのポインタ型も暗黙的にvoid*...に変換できるためです。


これに便利なオブジェクトをどのように割り当てますか?
user2681063 2013

22
@ user2681063 a = &userfulObject
Nikos C.

4
@MarkGarcia:void *a = a;ローカルで宣言されている場合はUBになることに注意してください。それ以外の場合は名前空間スコープで問題ありません。
Nawaz 2013

1
@TheodorosChatzigiannakis:そうだと思います。
Matthieu M.

1
スペックの引用はここで本当にいいでしょう。
Benjamin Gruenbaum 2013

30

に相当

void* a;
a = &a;

したがって、a宣言されています。だから、aのアドレス取得aに書かれたがa。したがって、これはvoidポインターへのポインターです。(まだオブジェクトを定義していません。)


9
技術的には、1つのオブジェクトを定義しました。aそれ自体がオブジェクトです。(C ++では、すべてのオブジェクトにユーザー定義型があるわけではありません)
MSalters 2013

1
@MSaltersあなたが言うこの「オブジェクト」は何ですか?:D
Gusdor 2013

3
@Gusdor私たちは、イベントの地平線の空白を超えたところにあるものだけを想定できます。
Cole Johnson

呼び方は異なりますが、この場合の「効果」は同じです
Stasik 2013

それらは一般に同等ではありませんが、このシナリオでは同等です。
オービットのライトネスレース

7

ではvoid* a、型ではなく「任意の」型(特殊な場合)aへのポインタとして宣言されていますvoid。アドレス(メモリ内の位置)が割り当てられますaもちろん、、宣言されている他の変数と同様ににます。

その後、式&aが評価され、a宣言されたばかりの変数が初期化されます(これも関係ありません)。の型&aは「任意の型へのポインタ」であり、「任意の型へのポインタ」の特殊なケースであり、の型と完全に互換性がありaます。エルゴ、コンパイラメッセージなし。

結果:void*強力な型チェックが必要な場合は使用しないでください。 何でもそれに変換できます。void*それ自体を除いて、逆方向の正反対です(型がそれ自体と互換性がないことは不要な例外です)。

また、AFAIRはCに由来しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.