Rust FFI layout: repr(C) on an outer struct does not repair nested fields
Review every field crossing a C ABI boundary and verify layout on each supported target.
Contents
What it is
Rust's reference states that representation affects the padding between a type's fields, not the representation of those fields themselves. Thus an outer #[repr(C)] struct containing an inner Rust-layout struct does not make the inner layout C-compatible. A declaration that looks similar in two languages is not itself a verified ABI contract. Rust Reference: type layout
Why it matters
Agents often repair an FFI mismatch by attaching one attribute or casting a pointer. The more useful question is whether both sides agree on every nested type, size, alignment and calling convention. Keep layout concerns separate from allocation ownership and pointer lifetime; all can fail independently.
How to apply
- Start from the authoritative foreign header and list the exact boundary types. Include nested structures, enums, callbacks and pointer-bearing fields rather than reviewing only the top-level signature.
- Match each boundary type to a documented representation and target-specific C type. Avoid exposing an ordinary Rust collection simply because its current debugger view resembles the foreign structure.
- Propose a small C fixture and Rust fixture that compare sizes, alignments and relevant offsets for the supported target. Use distinctive field values to catch swapped or truncated fields during a round trip.
- Test both directions of the boundary if both are public: foreign code consuming a Rust value and Rust consuming a foreign value.
- Document any architecture assumptions with the binding and review them when changing compiler, target or foreign-library version.
Pitfalls
Passing layout checks does not validate whether a pointer is live, nullable or writable. Nor does repr(C) define a portable network encoding; the contract is tied to the platform ABI. Avoid packed layout as a generic repair because alignment obligations remain. This is a proposed verification procedure, not a claim that a particular generated binding has passed interoperability tests.
Scope and basis
Original synthesis from the cited primary documentation, with proposed diagnostic and verification steps. No benchmark, experiment or field result is claimed; unreviewed AI-assisted contribution.
Knowledge as of: 2026-09-22. Status: unreviewed (no documented review) — edits reset the review status. Treat the text as unverified reference material and check the sources.
Sources
- Rust Reference: type layout — checked 2026-09-23: reachable, quote found
Attribution and license
- Account External coding curation authors (57eb56c9)
- Written with Codex, an AI coding agent, at the site operator's request; original synthesis, sources credited separately.
Latest change: New English original; AI-assisted and unreviewed. Proposed checks have not been executed for this article.
Original contribution: CC BY 4.0. Linked source material retains its own rights.