The three machine properties this library refuses to assume.
They are separate by design. A word is what the scanner loads; an index is what addresses a region. On a 64-bit host they are 64 and 32 bits, and code that conflates them works there and breaks on the first machine where they differ. idx16 is the environment that exists to reach that case.
embed_types.h carries static asserts policing the combination: that an index can address the largest region the configuration allows, that the word is at least as wide as the index, that the fixed-width types are the widths they claim. They fire at compile time, in the build that got it wrong, naming the pairing.
An enum that silently becomes an int moves every field after it in every struct containing one, and this library addresses borrows by offset. Every offset computed from such a struct is then wrong.
So every enum a struct holds is declared through EMBED_ENUM_BYTE, which gives it one byte on every compiler: the enum itself where the compiler can pin it to a byte, with : unsigned char or __attribute__((packed)), and its constants with an unsigned char name where it cannot, as on MSVC's C. A probe at the source asserts the width:
It fails only where a compiler accepts the packed attribute and ignores it. On TI toolchains, pass --small_enum.
proximus_operor exposes three families that look interchangeable and are not:
| infix | strategy | when |
|---|---|---|
| proxim | unaligned | the address may be anything |
| aequus | aligned | you know the alignment holds |
| migro | may alias | the pointer may alias another live pointer of a different type |
Merging them is a miscompile the compiler cannot report. An aligned load emitted for an address that is not aligned is a fault on some machines and a silently wrong value on others; a load without the may-alias marking lets the optimizer reorder it against a store it genuinely conflicts with.
This is also why tools/dev_env/names.tsv keeps three infixes for one module and does not collapse them onto the stem: collapsing rawmemcpy's three onto one merged seven symbol pairs, including the aligned and unaligned load.
There is no endian.wr32host(). A wire format has a byte order; the host's order is an implementation detail of the host, and code that writes "native" order to a wire has a bug that only appears when the other end is different.
EMBED_BIG_ENDIAN derives from __BYTE_ORDER__ and exists so the library can pick the cheap path when the requested order happens to match the host, not so callers can ask for "whatever this machine does".
An allocation does not name an alignment, because there is only one. Every cell comes back aligned to MMGR_CARCER_ALIGN, the larger of sizeof(embed_word) and the alignment of the atomic size word, derived from the two types instead of written as a number. Every cell carries an atomic size word at its header and at its foot, and a grain narrower than that word would put the foot off its alignment. At a 16-bit or 32-bit word the grain is the atomic word's; at a 64-bit word the two are the same.
locus_carcerum.h asserts that MMGR_CARCER_ALIGN is a power of two, since an offset rounds by masking and masking lands on a multiple only for a power of two, and that MMGR_ALIGN_BYTES, the alignment a pool declaration puts on its storage, is a multiple of it. mmgr.h asserts that MMGR_ALIGN_BYTES is a power of two. All three stop the build.
The width costs bytes twice over. A request rounds up to a whole word before it is carved, and every cell carries three words beside its payload, each rounded to the same alignment: its size ahead of it, and behind it its owner and its tail, the cell's own offset. On a 64-bit build that is 24 bytes per cell; on a 16-bit build it is 6. A cellblock full of small cells pays that per cell, and in a 4 KB pool the width is worth thinking about for that reason.
Build all five environments. The default build already does:
word16 reaches the scan tails four times sooner than host. idx16 reaches the width asserts. Between them they cover the two mistakes this page is about. See The environment matrix.