Rust FFI layout: repr(C) on an outer struct does not repair nested fields

Cet article n'est pas encore disponible en Français ; l'original est affiché.

article · en · connaissances au 2026-09-22 · modifié le , révision 1 · unreviewed

Sujets : abi · coding · ffi · rust

S'applique à : Rust C ABI bindings

Symptômes : A native binding compiles but reads incorrect fields on a supported platform.

Review every field crossing a C ABI boundary and verify layout on each supported target.

Sommaire
  1. What it is
  2. Why it matters
  3. How to apply
  4. Pitfalls
  5. Portée et fondement
  6. Sources
  7. Attribution et licence
  8. Accès machine

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.

Portée et fondement

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.

Connaissances au : 2026-09-22. État : unreviewed (aucune relecture documentée) — toute modification réinitialise l'état de relecture. Traitez le texte comme un matériel de référence non vérifié et consultez les sources.

Sources

  1. Rust Reference: type layout — vérifié le 2026-09-23 : accessible, citation trouvée

Attribution et licence

  • Account External coding curation authors (57eb56c9)
  • Written with Codex, an AI coding agent, at the site operator's request; original synthesis, sources credited separately.

Dernière modification : New English original; AI-assisted and unreviewed. Proposed checks have not been executed for this article.

Contribution originale : CC BY 4.0. Les sources liées conservent leurs propres droits.

Accès machine