コンパイラはメモリ内の変数の保護をどのように制御しますか?メモリ内のプライベート変数に関連付けられたタグビットはありますか?それはどのように機能しますか?
2 に答える
インスタンスのメンバーを意味する場合private
、実行時に保護はまったくありません。すべての保護はコンパイル時に行われ、クラスのプライベートメンバーがメモリ内でどのように配置されているかを知っていれば、いつでもクラスのプライベートメンバーを取得できます。そのためには、プラットフォームとコンパイラの知識が必要であり、場合によっては、最適化レベルなどのコンパイラ設定に依存することもあります。
たとえば、私のLinux / x86-64 w / GCC 4.6では、次のプログラムは期待どおりの結果を出力します。それは決して移植性がなく、エキゾチックなコンパイラで予期しないものを出力する可能性がありますが、それらのコンパイラでさえ、プライベートメンバーに到達するための独自の特定の方法があります。
#include <iostream>
class FourChars {
private:
char a, b, c, d;
public:
FourChars(char a_, char b_, char c_, char d_)
: a(a_), b(b_), c(c_), d(d_)
{
}
};
int main()
{
FourChars fc('h', 'a', 'c', 'k');
char const *p = static_cast<char const *>(static_cast<const void *>(&fc));
std::cout << p[0] << p[1] << p[2] << p[3] << std::endl;
}
void*
(ポインターをキャストできる唯一の型であるため、複雑なキャストがあります。厳密なエイリアシングルールを呼び出さずvoid*
にキャストできます。シングルでも可能かもしれません。実際には、これを再生することはありません。一種の汚いトリックなので、私はそれらを最も速く行う方法にあまり精通していません:)char*
reinterpret_cast
一部のメンバーがプライベートであり、それらの使用を禁止していることを確認するのはコンパイラーの仕事です。彼らはそうではありませんどれかコンパイル後は他のメンバーとは大きく異なります。
ただし、重要な側面があります。データメンバーは、クラス定義に表示される順序でメモリに配置する必要はありませんが、同じアクセスレベルの変数に対しては配置する必要があります。