C ++標準によると、オブジェクトが元々それ自体でない場合は、ポインタから離れconst
てオブジェクトに書き込むことができます。const
だからこれ:
const Type* object = new Type();
const_cast<Type*>( object )->Modify();
大丈夫ですが、これは:
const Type object;
const_cast<Type*>( &object )->Modify();
UBです。
その理由は、オブジェクト自体がオブジェクトである場合const
、コンパイラはそのオブジェクトへのアクセスを最適化できるためです。たとえば、繰り返しの読み取りは変更されないオブジェクトでは意味がないため、繰り返しの読み取りは実行されません。
問題は、コンパイラが実際にどのオブジェクトであるかをどのように知るかということconst
です。たとえば、次の関数があります。
void function( const Type* object )
{
const_cast<Type*>( object )->Modify();
}
そしてそれは静的ライブラリにコンパイルされ、コンパイラはそれがどのオブジェクトに対して呼び出されるかを知りません。
これで、呼び出し元のコードでこれを実行できます。
Type* object = new Type();
function( object );
そしてそれは大丈夫でしょう、またはそれはこれを行うことができます:
const Type object;
function( &object );
そしてそれは未定義の振る舞いになります。
コンパイラはこのような要件にどのように準拠する必要がありますか?後者を機能させずに前者を機能させるにはどうすればよいでしょうか。