C では、未定義の動作を呼び出すことなく、クラスの静的メンバーに Null ポインターを介してアクセスできます。この動作は、驚くべきことのように思えるかもしれませんが、言語の定義と理論的根拠を調べることで説明できます。
null ポインタを介してクラス メンバーにアクセスする場合、その動作は適切です。オペランドの評価が参照対象の ID や格納された値を必要としない限り、定義されます。たとえば、静的メンバー変数 d->a にアクセスすると、式 *(d) が評価されてオブジェクトへの参照が取得されるだけで、参照先の初期化が必要な操作は実行されません。
この評価このプロセスは [expr.ref]/2 によってサポートされており、これは d->a が ((d)).a に変換されることを示しています。 *d で表される ((d)) の評価は、d で参照されるオブジェクトが必要ないため、エラーを引き起こすことなく続行されます。
C 標準では、null ポインタを介した間接指定が本質的に未定義の動作を引き起こすとは明示的に述べていません。実際、CWG 問題 #232 と #315 は、単なる間接化には問題がないことを示唆しています。
この立場の主な議論は、null ポインターによる間接化が許可される、明確に定義されたシナリオの存在にあります。たとえば、[expr.typeid]/2 では、*d が null と評価される場合でも、typeid(*((A*)0)) が bad_typeid 例外をスローできます。単なる間接指定で UB が呼び出された場合、このステートメントは明確に定義されていません。
この例では、
<code class="cpp">int main() { demo* d = nullptr; d->fun(); std::cout << d->a; return 0; }</code>
プログラムはコンパイルされずに実行されます。静的メンバー関数の呼び出しや静的変数へのアクセスには参照先の ID が必要ないため、エラーが発生します。したがって、プログラムには固有の問題や未定義の動作はありません。
以上が未定義の動作をせずに Null ポインターを使用して C の静的メンバーにアクセスできますか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。