www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - bitfields

reply novice2 <sorry noem.ail> writes:
does anyone know: is D2 std.bitmanip compatible with C bitfields?
can i use it, if i need translate .h file with something like this:

typedef struct {
    unsigned int can_compress : 1;
    unsigned int can_uncompress : 1;
    unsigned int can_get_info : 1;
    unsigned int : 7;
    unsigned int : 16;
    unsigned int : 16;
    unsigned int : 16;
    unsigned int : 16;
    unsigned int : 16;
} capabilities;

Thanks.
Jun 18 2009
next sibling parent reply Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Thu, Jun 18, 2009 at 9:16 AM, novice2<sorry noem.ail> wrote:
 does anyone know: is D2 std.bitmanip compatible with C bitfields?
 can i use it, if i need translate .h file with something like this:

 typedef struct {
 =A0 =A0unsigned int can_compress : 1;
 =A0 =A0unsigned int can_uncompress : 1;
 =A0 =A0unsigned int can_get_info : 1;
 =A0 =A0unsigned int : 7;
 =A0 =A0unsigned int : 16;
 =A0 =A0unsigned int : 16;
 =A0 =A0unsigned int : 16;
 =A0 =A0unsigned int : 16;
 =A0 =A0unsigned int : 16;
 } capabilities;

 Thanks.
Theoretically speaking, it's not possible to answer your question because the ordering, padding, and arrangement of bitfields in C is not defined. It's entirely possible to have two different C compilers output different code for the same bitfield definitions. For that reason, it may not be possible to interface with the corresponding C library with any other language than C or any other compiler than the one it was compiled with. Practically speaking, sure. Most C compilers will take the path of least resistance and just pack all the bitfields together as tightly as they can starting with the LSB, and that is - AFAIK - what std.bitmanip's bitfield support does. But there are no guarantees.
Jun 18 2009
next sibling parent bearophile <bearophileHUGS lycos.com> writes:
Jarrett Billingsley:
 Practically speaking, sure.  Most C compilers will take the path of
 least resistance and just pack all the bitfields together as tightly
 as they can starting with the LSB, and that is - AFAIK - what
 std.bitmanip's bitfield support does.  But there are no guarantees.
This is good place where to use lot of D unittests. Bye, bearophile
Jun 18 2009
prev sibling parent reply novice2 <sorry noem.ail> writes:
Jarrett Billingsley Wrote:

 It's entirely possible to have two different C compilers
 output different code for the same bitfield definitions.  For that
Dut how is include files for interfacing is published officialy? For example Sun Java SDK .h files have bitfields to interfacing with java VM (without specifing wich compiler must be used). OK. I get you point and ofcause will try to experiment (i will try to compare diasm of C and D versions). thanx.
Jun 18 2009
parent Jarrett Billingsley <jarrett.billingsley gmail.com> writes:
On Thu, Jun 18, 2009 at 10:28 AM, novice2<sorry noem.ail> wrote:
 Jarrett Billingsley Wrote:

 It's entirely possible to have two different C compilers
 output different code for the same bitfield definitions. =A0For that
Dut how is include files for interfacing is published officialy? For exam=
ple Sun Java SDK .h files have bitfields to interfacing with java VM (witho= ut specifing wich compiler must be used). I would imagine they're depending on undefined behavior and just hoping for the best ;) As I said, most compilers do what you'd expect them to, it's just that there's the possibility that they won't.
Jun 18 2009
prev sibling parent reply downs <default_357-line yahoo.de> writes:
novice2 wrote:
 does anyone know: is D2 std.bitmanip compatible with C bitfields?
 can i use it, if i need translate .h file with something like this:
 
 typedef struct {
     unsigned int can_compress : 1;
     unsigned int can_uncompress : 1;
     unsigned int can_get_info : 1;
     unsigned int : 7;
     unsigned int : 16;
     unsigned int : 16;
     unsigned int : 16;
     unsigned int : 16;
     unsigned int : 16;
 } capabilities;
 
 Thanks.
Here's a way to do it. Enjoy! :) Usage example: struct Test { ushort bits; mixin GroupPackedAccess!(bits, ubyte, "stuff", 3, bool, "otherstuff" ); } module packed; template PackedAccessTools(string NAME, int from, int to) { const max = 1 << (to-from); static if (to >= 32) static assert(false, "Too large"); else static if (to >= 16) alias uint type; else static if (to >= 8) alias ushort type; else alias ubyte type; // 0 .. 4 -> ((1 << 4):16 - 1):15 & ~0 -> 7 == 1111 // 4 .. 8 -> ((1 << 8):256 - 1):255 & ~((1 << 4): 16 - 1):15 -> 11110000 const type mask = ((1 << to) - 1) - ((1 << from) - 1); const ID = NAME~"_"~from.stringof~"_"~to.stringof; } template PackedAccess(alias VAR, T, string NAME, int from, int to) { mixin(ctReplace(` T NAME() { static if (is(T == bool)) return (VAR & (°.mask)) != 0; else return cast(T) ((VAR & (°.mask)) >> from); } T NAME(T nv) { Assert(nv < °.max, "Value too big"); VAR &= (~°.mask); VAR |= (nv << from); return nv; } `, "NAME", NAME, "°", "PackedAccessTools!(NAME, from, to)", "·", PackedAccessTools!(NAME, from, to).ID )); } template NaturalTypeSize(T) { static if (is(T==bool)) const NaturalTypeSize = 1; else static assert(false, "No known default size for "~T.stringof~"!"); } template GroupPackedAccess(alias VAR, T...) { static if (T.length > 2) { static if (is(typeof(T[0])==void)) { static if (is(typeof(T[4]): int) && !is(T[4]: int)) { mixin PackedAccess!(VAR, T[2], T[3], T[1], T[1]+T[4]); mixin GroupPackedAccess!(VAR, void, T[1]+T[4], T[5 ..$]); } else { mixin PackedAccess!(VAR, T[2], T[3], T[1], T[1]+NaturalTypeSize!(T[2])); mixin GroupPackedAccess!(VAR, void, T[1]+NaturalTypeSize!(T[2]), T[4 ..$]); } } else { mixin GroupPackedAccess!(VAR, void, 0, T); } } }
Jun 27 2009
parent reply novice2 <sorry noem.ail> writes:
downs Wrote:
 
 Here's a way to do it.
 
 Enjoy! :)
 
 Usage example:
 
 struct Test {
  ... skipped...
Thank you, downs, for your job! but, heh, i can't use something, that i can't understand :( i hate template and mixin (imho it lead to full unreadable code). so with my dumbness, i need deveral weeks to understand this :)
Jun 28 2009
parent downs <default_357-line yahoo.de> writes:
novice2 wrote:
 downs Wrote:
 Here's a way to do it.

 Enjoy! :)

 Usage example:

 struct Test {
  ... skipped...
Thank you, downs, for your job! but, heh, i can't use something, that i can't understand :( i hate template and mixin (imho it lead to full unreadable code). so with my dumbness, i need deveral weeks to understand this :)
PackedAccessTools contains a few useful definitions given a bitfield variable name and a from..to bits-used range. PackedAccess uses ctReplace (compile-time search&replace, from scrapple.tools.base), to generate accessors that cut out (or set) a bit of a variable. This is the meat of PackedAccess. NaturalTypeSize is just the "default" size for a type. And GroupPackedAccess is just a wrapper template for PackedAccess. All it does is split its parameter tuple into groups that are used to instantiate PackedAccess. Feel free to ask if you have more specific questions.
Jun 30 2009