7

私の検索foo​​は今日欠けているようです。

std C ++に従って、(unsigned(?))char*を介して「任意の」メモリ位置を検査することが合法かどうかを知りたいです。任意の場所とは、プログラム内のオブジェクトまたは配列(または配列内)の有効なアドレスを意味します。

例として:

void passAnyObjectOrArrayOrSomethingElseValid(void* pObj) {
   unsigned char* pMemory = static_cast<unsigned char*>(pObj)
   MyTypeIdentifyier x = tryToFigureOutWhatThisIs(pMemory);
}

免責事項:この質問は純粋に学術的なものです。これを本番コードに入れるつもりはありません!合法とは、標準に従って本当に合法であるかどうか、つまり、すべての実装の100%で機能するかどうかを意味します。(x86や一部の一般的なハードウェアだけではありません。)

サブ質問:static_castvoid*アドレスからchar*ポインターに到達するための適切なツールはありますか?

4

3 に答える 3

8

C ++は厳密なエイリアシングを想定しています。つまり、根本的に異なるタイプの2つのポインターは、同じ値をエイリアシングしません。

ただし、bdonlanによって正しく指摘されているように、標準ではcharunsigned charポインタが例外になっています。

したがって、一般に、これは、任意のポインタタイプが任意の意図的なアドレス(任意のタイプである可能性があります)を読み取るための未定義の動作ですunsigned charが、質問のような特定の場合には許可されます(ISO 14882:2003 3.10(15))。

static_castコンパイル時の型チェックを行うため、常に機能するとは限りません。そのような場合、あなたは欲しいでしょうreinterpret_cast

于 2011-07-09T13:02:04.690 に答える
2

ISO / IEC 9899:1999(E)§6.5/ 7に準拠:

 7.オブジェクトは、次のいずれかのタイプの左辺値式によってのみ、格納された値にアクセスする必要があります。

  • オブジェクトの有効なタイプと互換性のあるタイプ、
  • [...]
  • 文字タイプ

したがって、(Cでは)を介して(有効な)ポインタを逆参照して調べることは合法ですunsigned char。ただし、そこにある内容は特定されていません。tryToFigureOutWhatThisIs何を見ているのかを実際に理解するための明確な方法はありません。ここにはC++仕様のコピーはありませんが、互換性を維持するために同じ定義を使用していると思われます。

于 2011-07-09T15:55:56.023 に答える
0

使用できるのは、char*ではなく、のみunsigned char*です。を使用すると、unsigned char*厳密なエイリアシングルールが破られ、未定義の動作が呼び出されますが、の例外がありますchar*。ただし、読んだメモリを使って実際に何かをしようとすると、非常に疑わしく、未定義のことをする可能性が非常に高くなります。そのため、慣用的なC++コードではめったに行われません。

于 2011-07-09T13:06:03.380 に答える