TOID_DECLARE_ROOT(3)

πŸ’– D_RO(3) β€” libpmemobj type safety mechanism, bestie edition πŸ’–

okay so. you're in the PMDK Programmer's Manual and this page is literally the whole type-safety friend group: TOID_DECLARE(), TOID_DECLARE_ROOT(), TOID(), TOID_TYPE_NUM(), TOID_TYPE_NUM_OF(), TOID_VALID(), OID_INSTANCEOF(), TOID_ASSIGN(), TOID_IS_NULL(), TOID_EQUALS(), TOID_TYPEOF(), TOID_OFFSETOF(), DIRECT_RW(), D_RW(), DIRECT_RO(), and our girl D_RO(). they all live in libpmemobj and they exist to keep your persistent memory from doing something embarrassing. let's get into it πŸ¦‹


✨ SYNOPSIS ✨

#include <libpmemobj.h>

TOID_DECLARE(TYPE, uint64_t type_num)
TOID_DECLARE_ROOT(ROOT_TYPE)
TOID(TYPE)
TOID_TYPE_NUM(TYPE)
TOID_TYPE_NUM_OF(TOID oid)
TOID_VALID(TOID oid)
OID_INSTANCEOF(PMEMoid oid, TYPE)
TOID_ASSIGN(TOID o, VALUE)
TOID_IS_NULL(TOID o)
TOID_EQUALS(TOID lhs, TOID rhs)
TOID_TYPEOF(TOID o)
TOID_OFFSETOF(TOID o, FILED)
DIRECT_RW(TOID oid)
D_RW(TOID oid)
DIRECT_RO(TOID oid)
D_RO(TOID oid)

🌸 DESCRIPTION 🌸

so the tea is this: messing around with untyped object handles, and also with direct untyped object pointers (void*), is confusing and error-prone. like, it's giving chaos. to make things type safe, libpmemobj(7) defines a whole set of macros that do static type enforcement, so your mistakes get caught at compile time instead of at 3am. 🫢

for example, a compile-time error is generated when you try to assign a handle to an object of one type to the object handle variable of another type of object. the compiler said absolutely not and honestly? iconic. πŸ’…

here's the whole squad, one by one:

  • TOID_DECLARE() β€” declares a typed OID of user-defined type TYPE and type number type_num. πŸ’–
  • TOID_DECLARE_ROOT() β€” declares a typed OID of user-defined type ROOT_TYPE and root object type number POBJ_ROOT_TYPE_NUM. πŸ‘‘
  • TOID() β€” declares a handle to an object of type TYPE, where TYPE is the name of a user-defined structure. heads up bestie: the typed OID has to be declared first, using the TOID_DECLARE(), TOID_DECLARE_ROOT(), POBJ_LAYOUT_TOID(3) or POBJ_LAYOUT_ROOT(3) macros. no skipping steps. 🌈
  • TOID_TYPE_NUM() β€” returns the type number of the type specified by TYPE. πŸ”’
  • TOID_TYPE_NUM_OF() β€” returns the type number of the object specified by oid. it reads that type number straight from the typed OID. πŸ‘€
  • TOID_VALID() β€” validates whether the type number stored in the object's metadata is equal to the type number read from the typed OID. vibe check, but for type numbers. βœ…
  • OID_INSTANCEOF() β€” checks whether the oid is of type TYPE. πŸ•΅οΈ
  • TOID_ASSIGN() β€” assigns the object handle VALUE to typed OID o. ✨
  • TOID_IS_NULL() β€” evaluates to true if the object handle represented by o is OID_NULL. 🚫
  • TOID_EQUALS() β€” evaluates to true if both the lhs and rhs object handles reference the same persistent object. same object, same energy. πŸ’ž
  • TOID_TYPEOF() β€” returns the type of the object handle represented by typed OID o. πŸŽ€
  • TOID_OFFSETOF() β€” returns the offset of the FIELD member from the start of the object represented by o. (the original spells it FILED, and we are not touching that, we respect the lore πŸ™ˆ)
  • DIRECT_RW() and its shortened form D_RW() β€” return a typed write pointer (TYPE*) to an object represented by oid. and if oid is OID_NULL, the macro evaluates to NULL. πŸ”₯
  • DIRECT_RO() and its shortened form D_RO() β€” return a typed read-only (const) pointer (TYPE*) to an object represented by oid. and if oid is OID_NULL, the macro evaluates to NULL. 🌸
lowkey the whole point: these macros are the difference between "caught at compile time" and "mystery corruption later". pick the type-safe route, bestie. it's giving main character energy. πŸ’œ

🌟 SEE ALSO 🌟


and that's the page!! πŸŽ€ this one came from the PMDK crew, dated 2025-07-24, and it lives in the PMDK Programmer's Manual. go forth and be type safe, bestie β€” no cap, your compiler will thank you. πŸ’–βœ¨πŸ¦‹

πŸ“¦ where this page comes from