Language feature and operation table
Use this table when you know a language feature but need to confirm which operations support it.
Vmeans the behavior is verified without a special limitation.Lmeans the operation is supported with the limitation explained below.—means the operation does not make sense for that feature, such as asking a scalar integer for a dynamic length.
The maintained feature-operation-matrix.json contains the
same rows plus exact test methods, round-trip conditions, and limitation text used by repository validators.
Feature support
| Feature/manual | Parse | Debug | Address | Length | Serialize | Write | Update | Read value | Executable pair |
|---|---|---|---|---|---|---|---|---|---|
| Three-byte integers | V | V | V | V | V | V | V | V | integers-24 |
| Byte-bounded text encodings | V | V | V | V | V | V | V | V | bounded-encodings |
| Width-bounded LEB128 integers | V | V | V | V | V | V | L | V | leb128-integers |
| Exact fixed-point values | V | V | V | — | V | V | V | V | fixed-point-values |
| UUID and Windows GUID values | V | V | V | V | V | V | V | V | identifier-values |
| Conditional fields and tagged records | V | V | V | V | V | V | L | V | conditional-fields |
| Fixed primitives | V | V | V | — | V | V | V | V | fixed-primitives |
| Character buffers | V | V | V | V | V | V | V | V | character-buffers |
| Terminated strings | V | V | V | V | V | V | L | V | terminated-strings |
| Enums | V | V | V | — | V | V | V | V | enums |
| Portable bitfields | V | V | V | — | V | V | V | V | portable-bitfields |
| Fixed arrays | V | V | V | V | V | V | V | V | fixed-arrays |
| Runtime expression arrays | V | V | V | V | V | V | V | V | runtime-expression-arrays |
| Named nested structs | V | V | V | — | V | V | V | V | nested-structs |
| Inline structs | V | V | V | — | V | V | V | V | inline-structs |
| Typedefs | V | V | V | — | V | V | V | V | typedefs |
| Unions | V | V | V | — | V | V | V | V | unions |
| Pointers | L | V | V | — | L | L | V | L | pointers |
| Multi-level pointers | V | L | V | — | V | V | V | V | multi-pointers |
| Alignment/endian | V | V | V | — | V | V | V | V | alignment-and-endian-overrides |
| Bounded failures | V | V | V | V | V | V | V | V | bounded-failures |
| Invalid layouts | V | V | V | V | V | V | V | V | invalid-layouts |
Each pair in
manual-fixtures-v1.json contains a valid layout with exact bytes,
offsets, and values plus one invalid case and its stable error category. Tests execute the pairs on .NET 8 and
.NET 10.
Operation meanings
| Column | What the operation does |
|---|---|
| Parse | Reads a dynamic root or selected composite from a stream/span/memory |
| Debug | Performs a read and records byte ranges for visited values |
| Address | Finds a path's absolute stream position and restores caller position |
| Length | Counts a fixed/runtime array or terminated string |
| Serialize | Creates an array or writes to a span / IBufferWriter<byte> |
| Write | Encodes a root/selected value at the current stream position |
| Update | Finds and replaces storage after staged validation |
| Read value | Returns one direct value or checked typed mapping |
Every row is also compiled by the [CStructLayout] source generator: the matrix records "generated": "parity"
for a feature whose fixture the parity project (tests/CStructSharp.Generated.Parity) generates and compares with
the runtime - values, serialized bytes, addresses, and the failure at every truncated length - and the validator
checks that claim against the project's layout index. All 47 features are at parity; the
generated code series shows what each becomes in C#.
Supported does not mean equally appropriate. Memory input avoids a stream adapter when bytes are already available. Debugging adds diagnostic work. Updating has validation-before-commit behavior that a direct stream write does not. Use Choose an API for those tradeoffs.
The awaitable forms (ParseAsync and the other *Async reads, WriteAsync, UpdateAsync, ParseManyAsync, and
the generated Parse<Name>Async/Write<Name>Async/Records<Name>Async), the ReadOnlySequence<byte> inputs, and
the record sequences (ParseMany, the generated Records) add no column: each is an input or enumeration form of
an operation above and runs the same reader, so every row's status carries over. The matrix's asyncContract block
states the one rule they share (the stream is read with ReadAsync into a pooled buffer and the synchronous span
reader runs over it), the position each form leaves a stream at, which forms need a seekable stream, where a
stored pointer address counts from, and how cancellation surfaces, each with the test that pins it;
memoryIoContract.inputApis lists the sequence overloads beside the span and memory ones. The guides are
async and pipelines and, for the generated forms,
sequences and TryParse.
Limited rows
A terminated-string update cannot grow beyond the existing storage plan or move later fields.
Pointer parsing, selected reads, and writes require explicit coordinate and following rules. Serialization writes addresses; it does not relocate target objects. Multi-level-pointer debugging records pointer storage but does not add a separate final primitive target range on every route.
Binary metadata type limits
Three-byte integers: No enum or bitfield backing; alignment is 1.
Byte-bounded text encodings: Counts are encoded bytes; strict decoding; shorter writes zero-pad. One-dimensional bounded arrays only.
Width-bounded LEB128 integers: Legal padded reads are accepted; canonical writes can change byte width. Updates require unchanged encoded extent. Static size is unknown.
Exact fixed-point values: No rounding, integer-expression projection, enum backing or bitfield backing.
UUID and Windows GUID values: Storage order is chosen by the type, not layout endianness. Identifiers cannot supply integer expressions.
Conditional fields and tagged records: Only active fields exist. Inactive selection fails and updates cannot change branch decisions or storage ranges. Update validation reads the complete root.