0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

クラスは空でもサイズは1バイト

Last updated at Posted at 2023-02-21

空のクラスサイズ

数年に1度、空のクラスを作りたくなることってありますよね?
クラスのサイズがどうなっているか興味はないでしょうか?

タイトルでネタバレしていますが、クラスは空でもサイズは1バイトです。
コンパイラ依存かもしれませんが、Visual C++, gccでも1バイトです。

空のクラスサイズ
#include <iostream>

class A{};

int main()
{
	std::cout << sizeof(A);
	return 0;
}
結果
1

なぜ1バイトなのかという考察ですが、メモリアドレス確保のために0では無理なので、1バイト以上になります。
あとはどんな数字でも良いのですが、最小の1バイトが選択されたのだと思います。

メンバ変数もないのだからnullptrの返却でいいのじゃないかと個人的には思います。アドレスも不要でしょう。
でもnewでnullptrが返却されたら不安になるか…

空のクラスの初期値

C++プログラマ発展のために科学黒魔術的実験が必要だと思うので試してみました。
誰も使ってない領域なのだから、作業領域として活用しても問題ないですよね? (ネタで言っていますのでご注意ください)

初期値がどうなっているのか確認しました。

空のクラスの初期値
#include <iostream>

class A {};

void hoge(A* a)
{
	std::cout << (int)(*((uint8_t*)a)) << std::endl;
}

int main()
{
	A a;
    /* 関数経由の回りくどい書き方をしている理由はVisual C++で
       変数aが初期化されていないエラーを回避するためです。*/
	hoge(&a);
	return 0;
}
結果(Visual C++ Releaseビルド/gcc)
0
結果(Visual C++ Debugビルド)
201

0で初期化されている優しさ(?)はありましたが、Visual C++のDebugとReleaseで挙動が変わるのはいただけません。
初期値0の変数として使うのは控えた方が良さそうです。

空のクラスのアクセス

次に書き換えが可能か確認しました。

空のクラスの書き換え
#include <iostream>

class A {};

int main()
{
	A a;
    /* ここで初期化(?)を行ったので
       Visual C++のエラーを回避できます。*/
	*((uint8_t*)&a) = 10;
	std::cout << (int)(*((uint8_t*)&a)) << std::endl;
	return 0;
}
結果
10

こちらは問題なさそうですね。
他に配列にしてみたり、newしてヒープ領域ならどうなるかなど試してみましたが結果は同じでした。

特にオチはないですが、ここまでです。
空のクラスのご利用は計画的に!

0
1
8

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?