Rust: поддержка битовых полей для C-взаимодействия

Созданный на 22 авг. 2013  ·  14Комментарии  ·  Источник: rust-lang/rust

В некоторых C API есть структуры, использующие битовые поля, и прямо сейчас их довольно громоздко использовать из ржавчины. Возможно, у нас должна быть какая-то поддержка для этого или, по крайней мере, макрос, который позаботится об этом.

Это было сделано специально для Azure, используемого в Servo.

Самый полезный комментарий

Я просто наткнулся на эту проблему, читая о Rust. Мне было интересно узнать о битовых полях, потому что я занимаюсь разработкой встроенного кода C/C++, и мы используем битовые поля для выражения состояния устройства, подключенного к UART. Состояние довольно большое, но благодаря битовым полям оно не так уж и плохо. Очень удобно помечать логические значения, некоторые небольшие целые числа и перечисления как от одного до нескольких битов из-за низких ограничений памяти. Я не уверен, что Rust стремится работать на устройстве с диапазоном памяти от 4 КБ до 16 КБ, но я бы не стал использовать Rust, если бы мне требовалось использовать макросы для получения однобитных флагов. Битовые поля допускают код очень высокого уровня, где макросы делают нечитаемое раздувание. Там, где требуется совместимость ABI/специфического выравнивания, конечно, макросы могут быть единственным выбором. Возможно, такие проекты, как Servo или другие будущие движки Javascript в Rust, могут внутри использовать битовые поля для экономии памяти в определенных случаях.

Все 14 Комментарий

Кажется неизбежным. Я бы предпочел сначала попробовать макро-маршрут.

Мне это не кажется неизбежным... Я чувствую, что мы можем прекрасно обойтись, используя uint и явную маскировку. Некоторые макросы для поддержки битовых наборов, конечно, были бы хороши. Я подозреваю, что расположение битовых полей полностью выполнено в clang, а не в LLVM, хотя я могу ошибаться, из-за чего нам будет очень сложно поддерживать это.

Хотя, честно говоря, я никогда не понимал привлекательности битовых полей даже в C. Всегда казалось, что они передают контроль над компоновкой, маскировкой и всем остальным компилятору, но вы используете их только тогда, когда вам важны детали. -- именно тогда, когда я предпочел бы точно знать, что происходит.

Ядро Linux (и многие библиотеки) вообще избегают битовых полей, потому что генерация кода компилятором ненадежна. Выравнивание, порядок и макет оставлены на усмотрение реализации, поэтому нам придется поддерживать разные ABI: http://gcc.gnu.org/onlinedocs/gcc/Structures-unions-enumerations-and-bit_002dfields-implementation.html

Да, я в порядке, избегаю этого.

Означает ли это, что для того, чтобы сделать это в Servo, мы должны использовать прокладки C для получения/установки каждого поля, чтобы избежать этих проблем?

Я просто наткнулся на эту проблему, читая о Rust. Мне было интересно узнать о битовых полях, потому что я занимаюсь разработкой встроенного кода C/C++, и мы используем битовые поля для выражения состояния устройства, подключенного к UART. Состояние довольно большое, но благодаря битовым полям оно не так уж и плохо. Очень удобно помечать логические значения, некоторые небольшие целые числа и перечисления как от одного до нескольких битов из-за низких ограничений памяти. Я не уверен, что Rust стремится работать на устройстве с диапазоном памяти от 4 КБ до 16 КБ, но я бы не стал использовать Rust, если бы мне требовалось использовать макросы для получения однобитных флагов. Битовые поля допускают код очень высокого уровня, где макросы делают нечитаемое раздувание. Там, где требуется совместимость ABI/специфического выравнивания, конечно, макросы могут быть единственным выбором. Возможно, такие проекты, как Servo или другие будущие движки Javascript в Rust, могут внутри использовать битовые поля для экономии памяти в определенных случаях.

@RushPL : макросы Rust не похожи на макросы C. Они не являются текстовой заменой, а скорее манипулируют деревьями токенов с помощью сопоставления с образцом (декларативные макросы) или кода Rust (процедурные макросы). В некоторых случаях лучший синтаксис может быть обеспечен без них, но Rust уже широко использует макросы для таких вещей, как строки формата с проверкой типа ( std::fmt ).

Ну, это все равно потребует предоставления конкретных битовых номеров, верно? (следовательно, делая ошибку кода подверженной)
let some_state = int_from_bits!(object.state, 3, 5) // 5 bit number from bit 3
против
let some_state = object.some_state // compiler does all the magic as it should be

Ну, одна вещь, которую вы можете сделать, это сгенерировать struct с методами для доступа к нему. Потеря заключается в невозможности использовать его в константных выражениях из-за отсутствия в Rust возможности выполнения функций во время компиляции.

То же самое вы можете сделать с C или C ++, если не используете битовые поля, но является ли генерация кода хорошим ответом? Можно было бы пропустить поддержку дженериков и вместо этого сгенерировать весь код для разных типов. Во всяком случае, только мои 2 цента с точки зрения того, кто заботится о размере структур данных и простоте использования встроенных полей.

См.: RFC: битовые поля и сопоставление битов.
https://github.com/rust-lang/rfcs/pull/29

Решает ли эту проблему новый макрос bitflags! ?

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

Возможно, было бы разумно закрыть этот вопрос в любом случае, учитывая вялую реакцию и расплывчатые требования.

Эта проблема была перемещена в репозиторий RFC: rust-lang/rfcs#314.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги