Rust: C相互運用機能のビットフィールドをサポート

作成日 2013年08月22日  ·  14コメント  ·  ソース: rust-lang/rust

一部のCAPIにはビットフィールドを使用する構造体があり、これらは現在、錆びた状態から使用するのはかなり面倒です。 おそらく、これに対する何らかのサポート、または少なくともそれを処理するマクロが必要です。

これは、Servoで使用されるAzureで特に思いついたものです。

最も参考になるコメント

Rustについて読んでいるときに、この問題に遭遇しました。 私は多くの組み込みC / C ++コード開発を行っており、UART接続デバイスの状態を表現するためにビットフィールドを使用しているため、ビットフィールドに興味がありました。 状態はかなり大きいですが、ビットフィールドのおかげでそれほど悪くはありません。 メモリの制約が少ないため、ブール値、特定の小さな整数、列挙型を1ビットから数ビットとしてマークするのは非常に簡単です。 Rustが4KB〜16KBのメモリ範囲のデバイスで実行することを望んでいるかどうかはわかりませんが、マクロを使用してシングルビットフラグを取得する必要がある場合は、Rustを使用しません。 ビットフィールドを使用すると、マクロによって読み取り不能な肥大化が発生する非常に高レベルのコードが可能になります。 もちろん、ABI /特定のアライメントの互換性が必要な場合は、マクロが唯一の選択肢かもしれません。 おそらく、ServoやRustの将来のJavascriptエンジンのようなプロジェクトは、特定の場合にメモリを節約するためにビットフィールドを内部的に使用する可能性があります。

全てのコメント14件

避けられないようです。 最初にマクロルートを試してみたいと思います。

それは私には避けられないようには思えません...私たちは、uintsと明示的なマスキングを使用してうまくいくことができるように感じます。 もちろん、ビットセットをサポートするためのいくつかのマクロは問題ありません。 ビットフィールドのレイアウトはLLVMではなく完全にclangで行われていると思いますが、間違っている可能性があり、これをサポートするのは非常に困難です。

公平を期すために、Cでもビットフィールドの魅力を理解することはできませんでした。レイアウトやマスキング、その他すべての制御をコンパイラに引き継いでいるように見えましたが、細部に気を配る場合にのみ使用します。 -正確に何が起こっているのかを正確に知りたいとき。

Linuxカーネル(および多くのライブラリ)は、コンパイラのコード生成が信頼できないため、一般にビットフィールドを回避します。 配置、順序、レイアウトは実装に任されているため、さまざまなABIをサポートする必要があります:http: //gcc.gnu.org/onlinedocs/gcc/Structures-unions-enumerations-and-bit_002dfields-implementation.html

ええ、私はこれを避けても大丈夫です。

これは、サーボでこれを行うには、これらの問題を回避するために、Cシムを使用して各フィールドを取得/設定する必要があることを意味しますか?

Rustについて読んでいるときに、この問題に遭遇しました。 私は多くの組み込みC / C ++コード開発を行っており、UART接続デバイスの状態を表現するためにビットフィールドを使用しているため、ビットフィールドに興味がありました。 状態はかなり大きいですが、ビットフィールドのおかげでそれほど悪くはありません。 メモリの制約が少ないため、ブール値、特定の小さな整数、列挙型を1ビットから数ビットとしてマークするのは非常に簡単です。 Rustが4KB〜16KBのメモリ範囲のデバイスで実行することを望んでいるかどうかはわかりませんが、マクロを使用してシングルビットフラグを取得する必要がある場合は、Rustを使用しません。 ビットフィールドを使用すると、マクロによって読み取り不能な肥大化が発生する非常に高レベルのコードが可能になります。 もちろん、ABI /特定のアライメントの互換性が必要な場合は、マクロが唯一の選択肢かもしれません。 おそらく、ServoやRustの将来のJavascriptエンジンのようなプロジェクトは、特定の場合にメモリを節約するためにビットフィールドを内部的に使用する可能性があります。

@RushPL :RustマクロはCマクロとは異なります。 これらはテキストによる置換ではなく、パターンマッチング(宣言型マクロ)またはRustコード(手続き型マクロ)のいずれかを介してトークンツリーを操作します。 場合によっては、それらがなくてもより良い構文を提供できますが、Rustはすでに、型チェックされた形式の文字列( std::fmt )などにマクロを多用しています。

ええと、それでも特定のビット番号を提供する必要がありますよね? (したがって、コードエラーが発生しやすくなります)
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

さて、あなたができることの1つは、それにアクセスするためのメソッドを使用して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 評価