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.
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.
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
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.
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=
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.
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);
}
}
}
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 :)
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.