質問は理由を尋ねます。理由は次のとおりです。
これが許されるのは、メモリアドレスへのポインターを取得すると、言語はそれが何を指しているのかわからなくなるためです。変数、構造体の一部、ヒープ、スタックなど、何でもかまいません。したがって、書き込みを禁止することはできません。直接メモリ アクセスは常に安全ではなく、別の方法がある場合は避ける必要があります。
割り当て(またはインクリメントなど)で a の値を変更するのconst
を止めます。const
この種の突然変異は、const に対して実行できないことを保証できる唯一の操作です。
これを調べる別の方法は、静的コンテキスト (つまり、コンパイル時) と実行時コンテキストの分割です。たとえば、変数への割り当てを行う可能性のあるコードをコンパイルすると、言語は「それは許可されていません。const です」と言うことができ、それはコンパイル エラーです。この後、コードは実行可能ファイルにコンパイルされ、それが であるという事実const
は失われます。変数宣言 (および言語の残りの部分) は、コンパイラへの入力として記述されます。コンパイルされると、コードは関係ありません。const
s が変更されていないことを示すために、コンパイラで論理的な証明を行うことができます。コンパイルされたプログラムが実行され、コンパイル時にルールを破らないプログラムを作成したことがわかります。
ポインターを導入すると、実行時に定義できる動作が得られます。あなたが書いたコードは今では無関係であり、あなたはやりたいことを[しようと]することができます。ポインターが型付けされているという事実 (ポインター演算を許可し、ポインターの末尾のメモリを特定の型として解釈する) は、言語が何らかの助けを提供することを意味しますが、何かを行うことを妨げることはできません。ポインタはどこでも指すことができるため、保証はできません。コンパイラーは、ポインターを使用するコードで実行時にルールを破ることを止めることはできません。
つまり、ポインターは動的な動作とデータ構造を取得する方法であり、最も単純なコードを除いてすべてに必要です。
(上記には多くの注意点があります。つまり、コードのヒューリスティック、より洗練された静的解析バスは、一般的なコンパイラに広く当てはまります。)