<!-- verified-against: seed-llvm; examples: docs-examples-test -->
Traduire C, Rust, et des constructions Zig pour seed
Il s’agit d’un guide de construction, pas d’un tableau de bord linguistique. Traduisez d'abord l'invariant de propriété, puis choisissez le plus petit type de graine qui l'exprime. Le compilateur LLVM fait autorité en matière de syntaxe et de diagnostics.
Traductions de base
| Intention | C | Rust | Zig | seed construction et invariant |
|---|---|---|---|---|
| texte appartenant | char * + manuel free |
String |
tranche allouée | string; déplacez-le, clonez-le explicitement et revenez alloc_error en cas d'échec d'allocation |
| texte emprunté | const char * |
&str |
[]const u8 |
str; la provenance est vérifiée et aucun gratuit n'est requis |
| octets détenus | malloc/free tampon |
Vec<u8> |
ArrayList(u8) |
bytes; initialiser via des API sécurisées et valider uniquement les octets initialisés |
| octets partagés | pointeur compté par convention | Arc<[u8]> |
propriétaire partagé par convention | shared_bytes; clonez explicitement le handle et ne modifiez jamais la charge utile |
| enregistrement fixe | struct |
struct |
struct |
struct; ajouter @repr("c") seulement quand le C ABI est le contrat |
| pointeur facultatif | pointeur nullable | Option<NonNull<T>> |
pointeur facultatif | ?*mut T en code non sécurisé, ou Option pour une valeur saisie |
| résultat faillible | code retour + paramètre out | Result<T,E> |
!T union d'erreur |
Result<T,E>; utiliser ?, match, ou une opération de frontière explicite |
| agent de nettoyage | goto cleanup |
Drop garde |
defer |
destructeur plus nettoyage structuré ; les sorties normales sont exactes une fois |
| égratignure étendue | stack/manual arène | aréna ou propriétaire temporaire | répartiteur d'arène | region(capacity) { ... }; les valeurs et les points de vue ne peuvent pas échapper |
| index vérifié | vérification des limites du côté de l'appelant | slice[index] |
slice[index] |
values[index]; le compilateur abaisse un accès vérifié |
| scission disjointe | arithmétique du pointeur + preuve | split_at_mut |
deux tranches par convention | split_at_mut(index); le compilateur enregistre des vues disjointes exclusives |
| transfert de fil | mutex/channel convention | Send/Sync |
convention API thread-safe | spawn; send est requis, et les données partagées nécessitent également sync |
| résultat de la jointure de tâche | emplacement de résultat partagé | JoinHandle<Result<...>> |
descripteur de fil + résultat | résultat de la tâche tapé ou faillible spawn; rejoindre avant le nettoyage |
| Rappel C | pointeur de fonction + void * |
extern "C" fn |
callconv(.C) fn |
nommé mince fn(...) -> ...; l'état voyage dans un handle opaque explicite |
| rappel conservé | pointeur de fonction + contexte + détruire | Box<dyn FnOnce>/FnMut |
propriété closure/context | box fn ou fermeture en boîte uniquement dans les API Seed ; ne le passez jamais comme pointeur C |
| champ atomique | _Atomic T |
Atomic* |
std.atomic |
éléments atomiques bruts intégrés à l'intérieur du unsafe, enveloppés dans un coffre-fort étroit API |
| MMIO volatile | volatile accès au pointeur |
volatile dangereux API | @volatile accès au pointeur |
opérations volatiles brutes dans un adaptateur de pilote unsafe explicite |
| casting non contrôlé | Casting C | unsafe transmute |
@ptrCast |
opération explicite et dangereuse address-space/pointer avec un invariant documenté |
Procédure de traduction
- Identifiez à qui appartient l’allocation, le descripteur, la tâche ou la ressource étrangère.
- Transformez les paramètres empruntés en
str,[]T, oumut []Tseulement quand le il est prouvé que le propriétaire du support est en ligne pour l'appel. - Transformez chaque copie implicite d'une valeur possédée en un mouvement ou un
explicite
.clone(). - Transformez les codes d'erreur et les branches de nettoyage en
Resultainsi que des sorties structurées. - Conservez la mise en page étrangère dans les enregistrements
@repr("c")et conservez les appels étrangers à l'intérieurunsafeemballages avecINSTALL.mdexigences. - Courir
seed check --deep, alorsseed buildetseed test; les diagnostics sont la preuve que l'invariant traduit est incomplet, ce n'est pas une raison pour désactiver la propriété.
Non-traductions courantes
box fnn'est pas un pointeur de fonction C : il possède un environnement Seed et ne peut pas traverser unextern "c"frontière.- Un déplacement dynamique de
values[index]n'est pas converti silencieusement en runtime ensemble de nettoyage. Utilisez un index connu, une opération de suppression de collection explicite ou borrow/clone l'élément. - Une région n’est pas une arène mondiale. Le retour d'un propriétaire ou d'une vue lié à une région est rejeté car l'allocateur a déjà été libéré.
- Un pointeur brut n’est pas une preuve de validité ou de durée de vie. Conservez la preuve dans le adaptateur non sécurisé et exposer une opération sûre vérifiée aux appelants.