Rust: admitir campos de bits para la interoperabilidad de C

Creado en 22 ago. 2013  ·  14Comentarios  ·  Fuente: rust-lang/rust

Algunas API de C tienen estructuras que usan campos de bits, y estos son bastante engorrosos de usar en este momento. Quizás deberíamos tener algún tipo de soporte para esto, o al menos una macro que se encargue de ello.

Esto ha surgido específicamente con Azure utilizado en Servo.

Comentario más útil

Me topé con este problema mientras leía sobre Rust. Tenía curiosidad acerca de los campos de bits porque hago mucho desarrollo de código C/C++ integrado y usamos campos de bits para expresar el estado de un dispositivo conectado a UART. El estado es bastante grande pero gracias a los campos de bits no está tan mal. Es muy sencillo marcar los valores booleanos, ciertos números enteros pequeños y enumeraciones como de uno a pocos bits debido a las limitaciones de poca memoria. No estoy seguro de si Rust aspira a ejecutarse en un dispositivo con un rango de memoria de 4 KB a 16 KB, pero no usaría Rust si tuviera que usar macros para obtener indicadores de un solo bit. Los campos de bits permiten un código de muy alto nivel donde las macros hacen que se hinche ilegible. Cuando se necesita compatibilidad de alineación específica/ABI, por supuesto, las macros pueden ser la única opción. Quizás proyectos como Servo o futuros motores Javascript en Rust podrían usar internamente campos de bits para ahorrar memoria en casos específicos.

Todos 14 comentarios

Parece inevitable. Preferiría probar la ruta macro primero.

No me parece inevitable... Siento que podemos arreglárnoslas muy bien usando uniones y enmascaramiento explícito. Algunas macros para admitir conjuntos de bits estarían bien, por supuesto. Sospecho que el diseño de los campos de bits se realiza completamente en clang, no en LLVM, aunque podría estar equivocado, lo que haría que esto fuera un problema para nosotros.

Sin embargo, para ser justos, nunca entendí el atractivo de los campos de bits, incluso en C. Siempre parecía que estaba entregando el control sobre el diseño y el enmascaramiento y todo lo demás al compilador, pero solo los usa cuando le importan mucho los detalles. -- precisamente cuando prefiero saber exactamente lo que está pasando.

El kernel de Linux (y muchas bibliotecas) evitan los campos de bits en general, porque la generación de código del compilador no es confiable. La alineación, el orden y el diseño se dejan a la implementación, por lo que tendríamos que admitir diferentes ABI: http://gcc.gnu.org/onlinedocs/gcc/Structures-unions-enumerations-and-bit_002dfields-implementation.html

Sí, estoy bien evitando este.

¿Significa esto que para hacer esto en Servo tenemos que usar cuñas C para obtener/establecer cada campo para evitar estos problemas?

Me topé con este problema mientras leía sobre Rust. Tenía curiosidad acerca de los campos de bits porque hago mucho desarrollo de código C/C++ integrado y usamos campos de bits para expresar el estado de un dispositivo conectado a UART. El estado es bastante grande pero gracias a los campos de bits no está tan mal. Es muy sencillo marcar los valores booleanos, ciertos números enteros pequeños y enumeraciones como de uno a pocos bits debido a las limitaciones de poca memoria. No estoy seguro de si Rust aspira a ejecutarse en un dispositivo con un rango de memoria de 4 KB a 16 KB, pero no usaría Rust si tuviera que usar macros para obtener indicadores de un solo bit. Los campos de bits permiten un código de muy alto nivel donde las macros hacen que se hinche ilegible. Cuando se necesita compatibilidad de alineación específica/ABI, por supuesto, las macros pueden ser la única opción. Quizás proyectos como Servo o futuros motores Javascript en Rust podrían usar internamente campos de bits para ahorrar memoria en casos específicos.

@RushPL : Las macros de Rust no son como las macros de C. No son una sustitución textual, sino que manipulan los árboles de tokens a través de la coincidencia de patrones (macros declarativos) o el código Rust (macros de procedimiento). En algunos casos, se puede proporcionar una mejor sintaxis sin ellos, pero Rust ya hace un uso intensivo de macros para cosas como cadenas de formato con verificación de tipo ( std::fmt ).

Bueno, todavía implicaría proporcionar números de bits específicos, ¿verdad? (por lo tanto, hace que el código sea propenso a errores)
let some_state = int_from_bits!(object.state, 3, 5) // 5 bit number from bit 3
contra
let some_state = object.some_state // compiler does all the magic as it should be

Bueno, una cosa que podrías hacer es generar un struct con métodos para acceder a él. La pérdida es la incapacidad de usarlo en expresiones constantes debido a la falta de ejecución de la función en tiempo de compilación de Rust.

Lo mismo que puede hacer con C o C ++ si no usa campos de bits, pero ¿generar código es una buena respuesta? Uno podría omitir el soporte de genéricos y, en su lugar, generar todo el código para diferentes tipos. De todos modos, solo mis 2 centavos desde la perspectiva de alguien que se preocupa por el tamaño de las estructuras de datos y la facilidad de uso de los campos incrustados.

Ver: RFC: campos de bits y coincidencia de bits
https://github.com/rust-lang/rfcs/pull/29

¿La nueva macro bitflags! soluciona este problema?

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

Podría ser prudente cerrar este problema de cualquier manera, dada la respuesta tibia y los requisitos vagos.

Este problema se ha movido al repositorio de RFC: rust-lang/rfcs#314

¿Fue útil esta página
0 / 5 - 0 calificaciones