空クラスのC++ではsizeof
1バイトなので、以下のコードは有効でしょうか?
class A
{
};
int main()
{
A a;
char* p = reinterpret_cast<char*>(&a);
*p = 'a';
}
ほとんど役に立たないことはわかっていますが、これができるかどうかを確認したかっただけです。MSVC2010 では問題なくコンパイルおよび実行されます。
空クラスのC++ではsizeof
1バイトなので、以下のコードは有効でしょうか?
class A
{
};
int main()
{
A a;
char* p = reinterpret_cast<char*>(&a);
*p = 'a';
}
ほとんど役に立たないことはわかっていますが、これができるかどうかを確認したかっただけです。MSVC2010 では問題なくコンパイルおよび実行されます。
C++03 標準 1.8 C++ オブジェクト モデル:
§1の関連部分:オブジェクトはストレージの領域です... 一部のオブジェクトは多相的です ... 他のオブジェクトの場合、そこにある値の解釈は、それらにアクセスするために使用される式のタイプによって決まります。"
あなたの例でa
は、実行がスコープを離れるときに割り当てが解除される自動保存期間を持つオブジェクトです。基本的に、それが存在するメモリは利用可能であり、必要なものをそこに保存できます。
int i;
char* myStr = reinterpret_cast<char*>(&i);
myStr[0] = 'H';
myStr[1] = 'i';
myStr[2] = '!';
myStr[3] = '\0';
std::cout << myStr;
(完全な例はこちら)
ここで考慮すべきことは、このように「乱用」するオブジェクトの存続期間です。つまり、オブジェクトの割り当てが解除された後でもこのメモリへのポインタを保持している場合、このメモリにアクセスすると未定義の動作が発生します。
言語で何かを実行できるからといって、それを実行する必要があるわけではないことに注意してください。この言語の機能は、意図されたとおりに使用してください。結局のところ、「機能する」ためだけにコードを書いているわけではありません。
また、空のクラスのサイズに関する質問に対して、標準の同じ部分にも次のように記載されています。
§4 : 完全なオブジェクト、データ メンバー (9.2)、または配列要素がクラス型である場合、その型は最派生クラスと見なされ、基底クラス サブオブジェクトのクラス型と区別されます。最派生クラス タイプのオブジェクトは、最派生オブジェクトと呼ばれます。
§5 : ビットフィールド (9.6) でない限り、最も派生したオブジェクトのサイズは 0 以外であり、ストレージの 1 バイト以上を占めるものとします。基本クラスのサブオブジェクトは、サイズがゼロの場合があります。POD 型 (3.9) のオブジェクトは、ストレージの連続するバイトを占有します。
したがって、標準では、あなたのような空のクラスのオブジェクトが少なくとも 1 バイトを占めることが保証されています。