Rust: unterstützt Bitfelder für C-Interop

Erstellt am 22. Aug. 2013  ·  14Kommentare  ·  Quelle: rust-lang/rust

Einige C-APIs haben Strukturen, die Bitfelder verwenden, und diese sind derzeit von Rust ziemlich umständlich zu verwenden. Vielleicht sollten wir dafür eine Art Unterstützung haben oder zumindest ein Makro, das sich darum kümmert.

Dies ist speziell bei Azure aufgetreten, das in Servo verwendet wird.

Hilfreichster Kommentar

Ich bin gerade über dieses Problem gestolpert, als ich über Rust gelesen habe. Ich war neugierig auf Bitfelder, weil ich viel eingebetteten C/C++-Code entwickle und wir Bitfelder verwenden, um den Zustand eines mit UART verbundenen Geräts auszudrücken. Der Staat ist ziemlich groß, aber dank Bitfields ist es nicht so schlimm. Es ist sehr sauber, die booleschen Werte, bestimmte kleine Ganzzahlen und Aufzählungen aufgrund geringer Speicherbeschränkungen als einzelne bis wenige Bits zu markieren. Ich bin mir nicht sicher, ob Rust darauf abzielt, auf einem Gerät mit 4 KB - 16 KB Speicherbereich ausgeführt zu werden, aber ich würde Rust nicht verwenden, wenn ich Makros verwenden müsste, um einzelne Bit-Flags zu erhalten. Bitfelder erlauben Code auf sehr hohem Niveau, bei dem Makros unlesbares Aufblähen verursachen. Wo ABI/spezifische Alignment-Kompatibilität benötigt wird, sind natürlich Makros die einzige Wahl. Vielleicht verwenden Projekte wie Servo oder andere zukünftige Javascript-Engines in Rust intern Bitfelder, um in bestimmten Fällen Speicher zu sparen.

Alle 14 Kommentare

Scheint unvermeidlich. Ich würde es vorziehen, zuerst die Makroroute auszuprobieren.

Es scheint mir nicht unvermeidlich ... Ich habe das Gefühl, dass wir mit Uints und expliziter Maskierung gut zurechtkommen. Einige Makros zur Unterstützung von Bitsets wären natürlich in Ordnung. Ich vermute, dass das Layout von Bitfeldern vollständig in Clang und nicht in LLVM erfolgt, obwohl ich mich irren könnte, was die Unterstützung für uns ziemlich mühsam machen würde.

Um fair zu sein, habe ich den Reiz von Bitfeldern selbst in C nie verstanden. Es schien immer so, als würde es die Kontrolle über Layout und Maskierung und den ganzen Rest an den Compiler übergeben, aber Sie verwenden sie nur, wenn Sie sich sehr um die Details kümmern -- genau dann, wenn ich lieber genau wissen möchte, was los ist.

Der Linux-Kernel (und viele Bibliotheken) vermeiden Bitfelder im Allgemeinen, da die Codegenerierung des Compilers unzuverlässig ist. Die Ausrichtung, Reihenfolge und das Layout bleiben der Implementierung überlassen, daher müssten wir verschiedene ABIs unterstützen: http://gcc.gnu.org/onlinedocs/gcc/Structures-unions-enumerations-and-bit_002dfields-implementation.html

Ja, ich bin in Ordnung, wenn ich das vermeide.

Bedeutet dies, dass wir, um dies in Servo zu tun, C-Shims verwenden müssen, um jedes Feld zu erhalten/einzustellen, um diese Probleme zu vermeiden?

Ich bin gerade über dieses Problem gestolpert, als ich über Rust gelesen habe. Ich war neugierig auf Bitfelder, weil ich viel eingebetteten C/C++-Code entwickle und wir Bitfelder verwenden, um den Zustand eines mit UART verbundenen Geräts auszudrücken. Der Staat ist ziemlich groß, aber dank Bitfields ist es nicht so schlimm. Es ist sehr sauber, die booleschen Werte, bestimmte kleine Ganzzahlen und Aufzählungen aufgrund geringer Speicherbeschränkungen als einzelne bis wenige Bits zu markieren. Ich bin mir nicht sicher, ob Rust darauf abzielt, auf einem Gerät mit 4 KB - 16 KB Speicherbereich ausgeführt zu werden, aber ich würde Rust nicht verwenden, wenn ich Makros verwenden müsste, um einzelne Bit-Flags zu erhalten. Bitfelder erlauben Code auf sehr hohem Niveau, bei dem Makros unlesbares Aufblähen verursachen. Wo ABI/spezifische Alignment-Kompatibilität benötigt wird, sind natürlich Makros die einzige Wahl. Vielleicht verwenden Projekte wie Servo oder andere zukünftige Javascript-Engines in Rust intern Bitfelder, um in bestimmten Fällen Speicher zu sparen.

@RushPL : Rust-Makros sind nicht wie C-Makros. Sie sind keine Textsubstitution, sondern manipulieren Token-Bäume entweder über Musterabgleich (deklarative Makros) oder Rust-Code (prozedurale Makros). In einigen Fällen kann ohne sie eine bessere Syntax bereitgestellt werden, aber Rust macht bereits starken Gebrauch von Makros für Dinge wie typgeprüfte Formatzeichenfolgen ( std::fmt ).

Nun, es würde immer noch die Angabe bestimmter Bitnummern beinhalten, oder? (daher den Code fehleranfällig machen)
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

Nun, eine Sache, die Sie tun könnten, ist, ein struct mit Methoden für den Zugriff darauf zu generieren. Der Verlust ist die Unfähigkeit, es in konstanten Ausdrücken zu verwenden, da Rust keine Funktionen zur Kompilierzeit ausführt.

Das Gleiche können Sie mit C oder C++ tun, wenn Sie keine Bitfelder verwenden, aber das Generieren von Code eine gute Antwort ist? Man könnte die Unterstützung von Generika überspringen und stattdessen den gesamten Code für verschiedene Typen generieren. Wie auch immer, nur meine 2 Cent aus der Perspektive von jemandem, der sich um die Größe von Datenstrukturen und die Benutzerfreundlichkeit eingebetteter Felder kümmert.

Siehe: RFC: Bitfelder und Bitabgleich
https://github.com/rust-lang/rfcs/pull/29

Behebt das neue Makro bitflags! dieses Problem?

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

Angesichts der lauwarmen Reaktion und der vagen Anforderungen könnte es ratsam sein, dieses Problem so oder so zu schließen.

Dieses Problem wurde in das RFCs-Repo verschoben: rust-lang/rfcs#314

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen