Rust: campos de bits de suporte para interoperabilidade C

Criado em 22 ago. 2013  ·  14Comentários  ·  Fonte: rust-lang/rust

Algumas APIs C têm structs que usam campos de bits, e estes são bastante complicados de usar agora. Talvez devêssemos ter algum tipo de suporte para isso, ou pelo menos uma macro que cuide disso.

Isso surgiu especificamente com o Azure usado no Servo.

Comentários muito úteis

Acabei de me deparar com esse problema enquanto lia sobre Rust. Eu estava curioso sobre os campos de bits porque faço muito desenvolvimento de código C/C++ incorporado e usamos campos de bits para expressar o estado de um dispositivo conectado ao UART. O estado é bastante grande, mas graças aos bitfields não é tão ruim. É muito limpo marcar os booleanos, certos pequenos inteiros e enums como um ou poucos bits devido a restrições de memória baixa. Não tenho certeza se Rust pretende ser executado em um dispositivo com intervalo de memória de 4KB - 16KB, mas não usaria Rust se fosse necessário usar macros para obter sinalizadores de bit único. Os campos de bits permitem código de nível muito alto, onde as macros tornam o inchaço ilegível. Onde a compatibilidade de alinhamento ABI/específico é necessária, é claro que as macros podem ser a única opção. Talvez projetos como Servo ou futuros mecanismos Javascript em Rust possam usar campos de bits internamente para economizar memória em casos específicos.

Todos 14 comentários

Parece inevitável. Eu prefiro tentar a rota macro primeiro.

Não me parece inevitável... Sinto que podemos nos dar bem usando uints e mascaramento explícito. Algumas macros para suporte a bitsets seriam boas, é claro. Suspeito que o layout dos campos de bits seja feito inteiramente em clang, não em LLVM, embora eu possa estar errado, o que tornaria isso muito difícil para nós suportarmos.

Para ser justo, porém, eu nunca entendi o apelo dos campos de bits, mesmo em C. Sempre parecia que estava entregando o controle sobre o layout e o mascaramento e todo o resto para o compilador, mas você só os usa quando se importa muito com os detalhes -- precisamente quando eu preferiria saber exatamente o que está acontecendo.

O kernel Linux (e muitas bibliotecas) evitam campos de bits em geral, porque a geração de código do compilador não é confiável. O alinhamento, a ordem e o layout são deixados para a implementação, então teríamos que oferecer suporte a diferentes ABIs: http://gcc.gnu.org/onlinedocs/gcc/Structures-unions-enumerations-and-bit_002dfields-implementation.html

Sim, estou bem evitando este.

Isso significa que para fazer isso no Servo temos que usar C shims para obter/definir cada campo para evitar esses problemas?

Acabei de me deparar com esse problema enquanto lia sobre Rust. Eu estava curioso sobre os campos de bits porque faço muito desenvolvimento de código C/C++ incorporado e usamos campos de bits para expressar o estado de um dispositivo conectado ao UART. O estado é bastante grande, mas graças aos bitfields não é tão ruim. É muito limpo marcar os booleanos, certos pequenos inteiros e enums como um ou poucos bits devido a restrições de memória baixa. Não tenho certeza se Rust pretende ser executado em um dispositivo com intervalo de memória de 4KB - 16KB, mas não usaria Rust se fosse necessário usar macros para obter sinalizadores de bit único. Os campos de bits permitem código de nível muito alto, onde as macros tornam o inchaço ilegível. Onde a compatibilidade de alinhamento ABI/específico é necessária, é claro que as macros podem ser a única opção. Talvez projetos como Servo ou futuros mecanismos Javascript em Rust possam usar campos de bits internamente para economizar memória em casos específicos.

@RushPL : Macros Rust não são como macros C. Eles não são uma substituição textual, mas sim manipulam árvores de token por meio de correspondência de padrões (macros declarativos) ou código Rust (macros de procedimento). Em alguns casos, uma sintaxe melhor pode ser fornecida sem eles, mas o Rust já faz uso pesado de macros para coisas como strings de formato verificados por tipo ( std::fmt ).

Bem, ainda envolveria fornecer números de bits específicos, certo? (portanto, tornando o código propenso a erros)
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

Bem, uma coisa que você pode fazer é gerar um struct com métodos para acessá-lo. A perda é a incapacidade de usá-lo em expressões constantes devido à falta de execução da função em tempo de compilação do Rust.

A mesma coisa que você pode fazer com C ou C++ se não estiver usando campos de bits, mas gerar código é uma boa resposta? Pode-se ignorar o suporte a genéricos e, em vez disso, gerar todo o código para diferentes tipos. De qualquer forma, apenas meus 2 centavos da perspectiva de alguém que se preocupa com o tamanho das estruturas de dados e a facilidade de uso de campos incorporados.

Veja: RFC: campos de bits e correspondência de bits
https://github.com/rust-lang/rfcs/pull/29

A nova macro bitflags! resolve esse problema?

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

Pode ser prudente encerrar essa questão de qualquer maneira, dada a resposta morna e os requisitos vagos.

Este problema foi movido para o repositório de RFCs: rust-lang/rfcs#314

Esta página foi útil?
0 / 5 - 0 avaliações