Rust: prend en charge les champs de bits pour C interop

Créé le 22 août 2013  ·  14Commentaires  ·  Source: rust-lang/rust

Certaines API C ont des structures qui utilisent des champs de bits, et celles-ci sont plutôt lourdes à utiliser à partir de la rouille en ce moment. Peut-être devrions-nous avoir une sorte de support pour cela, ou au moins une macro qui s'en occupe.

Cela est venu spécifiquement avec Azure utilisé dans Servo.

Commentaire le plus utile

Je viens de tomber sur ce problème en lisant sur Rust. J'étais curieux de connaître les champs de bits parce que je fais beaucoup de développement de code C/C++ intégré et nous utilisons des champs de bits pour exprimer l'état d'un appareil connecté UART. L'état est assez grand mais grâce aux bitfields ce n'est pas trop mal. Il est très propre de marquer les booléens, certains petits entiers et énumérations comme simples à quelques bits en raison de faibles contraintes de mémoire. Je ne sais pas si Rust aspire à fonctionner sur un appareil avec une plage de mémoire de 4 Ko à 16 Ko, mais je n'utiliserais pas Rust si cela m'obligeait à utiliser des macros pour obtenir des drapeaux à un seul bit. Les champs de bits autorisent un code de très haut niveau où les macros créent un gonflement illisible. Lorsque la compatibilité ABI/alignement spécifique est nécessaire, bien sûr, les macros peuvent être le seul choix. Peut-être que des projets comme Servo ou d'autres futurs moteurs Javascript dans Rust pourraient utiliser en interne des champs de bits pour économiser de la mémoire dans des cas spécifiques.

Tous les 14 commentaires

Semble inévitable. Je préférerais d'abord essayer la voie macro.

Cela ne me semble pas inévitable... J'ai l'impression qu'on peut très bien s'en sortir en utilisant des uints et un masquage explicite. Certaines macros pour prendre en charge les bitsets conviendraient bien sûr. Je soupçonne que la mise en page des champs de bits est entièrement réalisée en clang, pas en LLVM, bien que je puisse me tromper, ce qui rendrait cela assez pénible à prendre en charge.

Pour être juste, je n'ai jamais compris l'attrait des champs de bits, même en C. Il a toujours semblé que cela donnait le contrôle de la mise en page et du masquage et tout le reste au compilateur, mais vous ne les utilisez que lorsque vous vous souciez beaucoup des détails - précisément quand je préfère savoir exactement ce qui se passe.

Le noyau Linux (et de nombreuses bibliothèques) évite les champs de bits en général, car la génération de code du compilateur n'est pas fiable. L'alignement, l'ordre et la mise en page sont laissés à l'implémentation, nous devrions donc prendre en charge différents ABI : http://gcc.gnu.org/onlinedocs/gcc/Structures-unions-enumerations-and-bit_002dfields-implementation.html

Ouais, je vais bien éviter celui-ci.

Cela signifie-t-il que pour ce faire dans Servo, nous devons utiliser des cales C pour obtenir/définir chaque champ afin d'éviter ces problèmes ?

Je viens de tomber sur ce problème en lisant sur Rust. J'étais curieux de connaître les champs de bits parce que je fais beaucoup de développement de code C/C++ intégré et nous utilisons des champs de bits pour exprimer l'état d'un appareil connecté UART. L'état est assez grand mais grâce aux bitfields ce n'est pas trop mal. Il est très propre de marquer les booléens, certains petits entiers et énumérations comme simples à quelques bits en raison de faibles contraintes de mémoire. Je ne sais pas si Rust aspire à fonctionner sur un appareil avec une plage de mémoire de 4 Ko à 16 Ko, mais je n'utiliserais pas Rust si cela m'obligeait à utiliser des macros pour obtenir des drapeaux à un seul bit. Les champs de bits autorisent un code de très haut niveau où les macros créent un gonflement illisible. Lorsque la compatibilité ABI/alignement spécifique est nécessaire, bien sûr, les macros peuvent être le seul choix. Peut-être que des projets comme Servo ou d'autres futurs moteurs Javascript dans Rust pourraient utiliser en interne des champs de bits pour économiser de la mémoire dans des cas spécifiques.

@RushPL : Les macros Rust ne sont pas comme les macros C. Il ne s'agit pas d'une substitution textuelle, mais plutôt de manipuler des arbres de jetons via la correspondance de modèles (macros déclaratives) ou le code Rust (macros procédurales). Dans certains cas, une meilleure syntaxe peut être fournie sans eux, mais Rust fait déjà un usage intensif des macros pour des choses comme les chaînes de format dont le type est vérifié ( std::fmt ).

Eh bien, cela impliquerait toujours de fournir des numéros de bits spécifiques, n'est-ce pas ? (ce qui rend le code sujet aux erreurs)
let some_state = int_from_bits!(object.state, 3, 5) // 5 bit number from bit 3
vs
let some_state = object.some_state // compiler does all the magic as it should be

Eh bien, une chose que vous pourriez faire est de générer un struct avec des méthodes pour y accéder. La perte est l'incapacité de l'utiliser dans des expressions constantes en raison du manque d'exécution de fonction au moment de la compilation de Rust.

La même chose que vous pouvez faire avec C ou C++ si vous n'utilisez pas de champs de bits mais que la génération de code est une bonne réponse ? On pourrait ignorer la prise en charge des génériques et générer à la place tout le code pour différents types. Quoi qu'il en soit, juste mes 2 cents du point de vue de quelqu'un qui se soucie de la taille des structures de données et de la facilité d'utilisation des champs intégrés.

Voir : RFC : champs de bits et correspondance de bits
https://github.com/rust-lang/rfcs/pull/29

La nouvelle macro bitflags! résout-elle ce problème ?

https://github.com/mozilla/rust/pull/13072

Il serait peut-être prudent de clore ce problème de toute façon, compte tenu de la réponse tiède et des exigences vagues.

Ce problème a été déplacé vers le référentiel RFC : rust-lang/rfcs#314

Cette page vous a été utile?
0 / 5 - 0 notes