std::optional 内存布局

发布时间 2023-07-26 16:04:21作者: gbcwbz

对于std::optional<int>对应的内存布局为

struct optional_mem {
	int _M_payload;
	bool _M_engaged;
};

可以通过godbolt通过pahole工具查看
image
在汇编窗口选择 pahole右侧会显示数据结构

class exception_ptr {
	void *                     _M_exception_object;  /*     0     8 */
public:


	/* size: 8, cachelines: 1, members: 1 */
	/* last cacheline: 8 bytes */
};
struct nullopt_t {

	/* size: 1, cachelines: 0, members: 0 */
	/* padding: 1 */
	/* last cacheline: 1 bytes */
};
class optional<int> : _Optional_base<int, true, true>, _Enable_copy_move<true, true, true, true, std::optional<int> > {
	/* struct _Optional_base<int, true, true> <ancestor>; */ /*     0     8 */

	/* XXX 65528 bytes hole, try to pack */

	/* struct _Enable_copy_move<true, true, true, true, std::optional<int> > <ancestor>; */ /*     0     0 */

	/* XXX last struct has 1 byte of padding */
public:


	/* size: 8, cachelines: 1, members: 2 */
	/* padding: 8 */
	/* paddings: 1, sum paddings: 1 */
	/* last cacheline: 8 bytes */

	/* BRAIN FART ALERT! 8 bytes != 0 (member bytes) + 0 (member bits) + 65528 (byte holes) + 0 (bit holes), diff = -524224 bits */
};
class _Optional_base_impl<int, std::_Optional_base<int, true, true> > {
protected:


	/* size: 1, cachelines: 0, members: 0 */
	/* padding: 1 */
	/* last cacheline: 1 bytes */
};
struct _Empty_byte {

	/* size: 1, cachelines: 0, members: 0 */
	/* padding: 1 */
	/* last cacheline: 1 bytes */
};
union _Storage<int, true> {
	struct _Empty_byte         _M_empty;           /*     0     0 */
	int                        _M_value;           /*     0     4 */
};
struct _Optional_payload_base<int> {
	union _Storage<int, true>  _M_payload;           /*     0     4 */
	bool                       _M_engaged;           /*     4     1 */

	/* size: 8, cachelines: 1, members: 2 */
	/* padding: 3 */
	/* last cacheline: 8 bytes */
};
struct _Optional_payload<int, true, true, true> : _Optional_payload_base<int> {
	/* struct _Optional_payload_base<int> <ancestor>; */ /*     0     8 */

	/* XXX last struct has 3 bytes of padding */

	/* size: 8, cachelines: 1, members: 1 */
	/* paddings: 1, sum paddings: 3 */
	/* last cacheline: 8 bytes */

	/* BRAIN FART ALERT! 8 bytes != 0 (member bytes) + 0 (member bits) + 0 (byte holes) + 0 (bit holes), diff = 64 bits */
};
struct _Optional_base<int, true, true> : _Optional_base_impl<int, std::_Optional_base<int, true, true> > {
	/* class _Optional_base_impl<int, std::_Optional_base<int, true, true> > <ancestor>; */ /*     0     0 */

	/* XXX last struct has 1 byte of padding */

	struct _Optional_payload<int, true, true, true> _M_payload; /*     0     8 */

	/* size: 8, cachelines: 1, members: 2 */
	/* paddings: 1, sum paddings: 1 */
	/* last cacheline: 8 bytes */
};
struct _Enable_copy_move<true, true, true, true, std::optional<int> > {

	/* size: 1, cachelines: 0, members: 0 */
	/* padding: 1 */
	/* last cacheline: 1 bytes */
};
class bad_optional_access : public exception {
public:

	/* class exception           <ancestor>; */      /*     0     0 */

	/* size: 8, cachelines: 1, members: 1 */
	/* padding: 8 */
	/* last cacheline: 8 bytes */
};

可以看到最终数据存储在

struct _Optional_payload_base<int> {
	union _Storage<int, true>  _M_payload;           /*     0     4 */
	bool                       _M_engaged;           /*     4     1 */

	/* size: 8, cachelines: 1, members: 2 */
	/* padding: 3 */
	/* last cacheline: 8 bytes */
};

中,_M_payload中存储实际数据