次のプログラムを考えてみましょう:
<code class="cpp">#include <iostream> class Demo { public: static void func() { std::cout << "func() called" << std::endl; } static int num = 9; }; int main() { Demo* d = nullptr; d->func(); std::cout << d->num << std::endl; return 0; }</code>
このプログラムはエラーなしでコンパイルおよび実行されますが、null ポインターを介した静的メンバーへのアクセスは一般に未定義の動作とみなされます。なぜこれが許可されているのですか?
TL;DR:
NULL ポインターを介した間接指定は許可されていないため、指定されたプログラムは未定義の動作をトリガーしません。有効なオブジェクト ID に依存するさらなる操作が含まれない限り、本質的に問題があります。
説明:
null ポインターを介した間接指定が本質的に未定義の動作であるかどうかは議論の余地があります。 。プログラム内で唯一疑わしい操作は、式 d->a の評価です。
d->a は、ポインター逆参照規則により (*d).a と同等です。ただし、*d が未定義の場合でも、式 *d は、特に d->a の場合のように結果が破棄される場合には評価されます。この動作は明確に定義されています。
静的メンバーの動作は、無効なオブジェクト ID を意味するため、実際に未定義の動作を引き起こすはずの、null ポインターを介した非静的メンバーへのアクセスとは異なります。対照的に、静的メンバーへのアクセスにはオブジェクト ID は必要なく、その動作は標準で明示的に定義されています。
静的メンバーにアクセスするコンテキストでは *d の評価が許可されているため、指定されたプログラムには害はありません。 Null ポインターだけによる間接指定は、必ずしも未定義の動作を引き起こすわけではありませんが、オブジェクト ID を必要とするさらなる操作に関連する潜在的なリスクを認識することが重要です。
以上がC で null ポインターを使用して静的メンバーにアクセスできるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。