Why a call reads EMBED_CALL(spat.from, SpatiumCfg, .buf = p, .cap = n) and what that costs.
Every module declares plain C functions with a long, prefixed name, and also gathers them into a static const struct of function pointers named for a short Latin stem.
Every entry takes exactly one argument: a pointer to that module's config struct. EMBED_CALL builds the struct as a compound literal and passes its address, and so the members are named at the call site and anything left out is zero:
the same call as
Both forms are public and both are documented. The table is what call sites use, because at a call site the module is context you already have and repeating it is noise:
The library keeps the free functions because they are what a debugger, a linker map and a nm listing show you, and a namespace built out of macros would show nothing.
Naming the members also means an entry cannot be called with its arguments in the wrong order, and an entry that grows a member does not silently change the meaning of existing call sites.
Three pieces, in every module header:
EMBED_TABLE_STORAGE is static const. EMBED_UNUSED lets an unreferenced table drop out of a translation unit that does not use it.
The table is addressed by offset. A positional initializer mis-wires silently when a member is inserted, removed or moved: the code still compiles, and spat.from calls something else.
EMBED_TABLE_LAYOUT pins it. It expands to a chain of _Static_asserts checking that each named member sits at its own loculus, in the order given, and that sizeof the struct is exactly that many pointers. A member added and not listed, a member reordered, or padding appearing between them all fail at the declaration, at compile time.
That has one consequence for this documentation: the order of the members is the layout, and so the reference must not sort them alphabetically. SORT_MEMBER_DOCS is NO in docs/Doxyfile for that reason, and it is not a cosmetic setting: sorting MemoriaOperorNs would show loculus 0 as chr when it is cpy.
Nothing, when const is respected.
Measured: gcc devirtualizes a call through a static const <Mod>Ns down to the inlined body, identical instructions to calling the entry directly, and does not devirtualize the same call through a non-const table, which becomes a real call with an 88-byte frame. clang devirtualizes both. So the const in EMBED_TABLE_STORAGE is essential: it makes the two compilers agree.
Across module boundaries where the entry is not EMBED_INLINE, link-time optimization is what closes the gap. See Doing eight bytes at a time for the measurement.
verbum_scrutor has three: lane, mask and word. The entries were one table until the count passed what EMBED_TABLE_LAYOUT accepts, and splitting them by what they operate on, a lane of a word, a mask of lanes, a whole word, reads better than one table of everything did.
endian is the other shape: two tables, parva_extremitas and magna_extremitas, over the same EndianNs type. The byte order is chosen by which table you call through and not by an argument.
The Latin, decoded lists every stem and the module it belongs to.