次のC ++コードを考えてみます。
void* a = &a;
宣言されていない識別子を使用するとコンパイラが文句を言わないのはなぜですか?
また、コンパイラは変数aを何と見なしていますか?それはvoidオブジェクトへのvoid*ポインターですか、それともポインターへのポインターですか?
次のC ++コードを考えてみます。
void* a = &a;
宣言されていない識別子を使用するとコンパイラが文句を言わないのはなぜですか?
また、コンパイラは変数aを何と見なしていますか?それはvoidオブジェクトへのvoid*ポインターですか、それともポインターへのポインターですか?
回答:
C ++での変数の宣言のスコープは、かなり驚くべきものです。
void* a = &a;
^~~~~~~~~~~~~~~~~
a declared as `void*` from here on
したがって、&aisですvoid**が、どのポインタ型も暗黙的にvoid*...に変換できるためです。
a = &userfulObject?
void *a = a;ローカルで宣言されている場合はUBになることに注意してください。それ以外の場合は名前空間スコープで問題ありません。
に相当
void* a;
a = &a;
したがって、a宣言されています。だから、aのアドレス取得aに書かれたがa。したがって、これはvoidポインターへのポインターです。(まだオブジェクトを定義していません。)
aそれ自体がオブジェクトです。(C ++では、すべてのオブジェクトにユーザー定義型があるわけではありません)
ではvoid* a、型ではなく「任意の」型(特殊な場合)aへのポインタとして宣言されていますvoid。アドレス(メモリ内の位置)が割り当てられますaもちろん、、宣言されている他の変数と同様ににます。
その後、式&aが評価され、a宣言されたばかりの変数が初期化されます(これも関係ありません)。の型&aは「任意の型へのポインタ」であり、「任意の型へのポインタ」の特殊なケースであり、の型と完全に互換性がありaます。エルゴ、コンパイラメッセージなし。
結果:void*強力な型チェックが必要な場合は使用しないでください。 何でもそれに変換できます。void*それ自体を除いて、逆方向の正反対です(型がそれ自体と互換性がないことは不要な例外です)。
また、AFAIRはCに由来しています。