www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Need help with movement from C to D

reply "Andrey" <none none.no> writes:
Guys, could someone help me with suitable template?

I have C macro, which calculates the offset of the field in a 
struct:

#define offsetof(type, field)	((long) &((type *)0)->field)

A similar D code is, as far as I know,

type.field.offsetof

Is there an any way to make a corresponding D template?

Thank you!
May 04 2014
next sibling parent reply "Mark Isaacson" <turck11 hotmail.com> writes:
On Monday, 5 May 2014 at 03:57:54 UTC, Andrey wrote:
 Guys, could someone help me with suitable template?

 I have C macro, which calculates the offset of the field in a 
 struct:

 #define offsetof(type, field)	((long) &((type *)0)->field)

 A similar D code is, as far as I know,

 type.field.offsetof

 Is there an any way to make a corresponding D template?

 Thank you!
Something like: unittest { enum offsetof(string type, string field) = mixin(type ~ "." ~ field ~ ".offsetof"); struct StrToBob { string str; int bob; } writeln(offsetof!("StrToBob", "bob")); } ? If not that then I'm not sure what you're asking for.
May 04 2014
next sibling parent "Andrey" <none none.no> writes:
On Monday, 5 May 2014 at 04:05:35 UTC, Mark Isaacson wrote:

   enum offsetof(string type, string field) = mixin(type ~ "." ~ 
 field ~ ".offsetof");
That's exactly what I'm looking for!!
May 05 2014
prev sibling parent reply "Meta" <jared771 gmail.com> writes:
On Monday, 5 May 2014 at 04:05:35 UTC, Mark Isaacson wrote:
 Something like:

 unittest {
   enum offsetof(string type, string field) = mixin(type ~ "." ~ 
 field ~ ".offsetof");

   struct StrToBob {
     string str;
     int bob;
   }

   writeln(offsetof!("StrToBob", "bob"));
 }

 ?

 If not that then I'm not sure what you're asking for.
That enum template might be better like this: enum offsetof(T, string field) = mixin(type.stringof ~ "." ~ field ~ ".offsetof"); To ensure that a syntactically valid symbol is passed as the type.
May 05 2014
parent reply "Andrey" <none none.no> writes:
On Monday, 5 May 2014 at 17:55:37 UTC, Meta wrote:

 enum offsetof(T, string field) = mixin(type.stringof ~ "." ~ 
 field ~ ".offsetof");

 To ensure that a syntactically valid symbol is passed as the 
 type.
Interestingly, but this code doesn't compile: enum offsetof(typenfield) = mixin(type.stringof ~ ".offsetof"); writeln(offsetof!(StrToBob.bob));
May 06 2014
parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Tuesday, 6 May 2014 at 11:09:37 UTC, Andrey wrote:
 On Monday, 5 May 2014 at 17:55:37 UTC, Meta wrote:

 enum offsetof(T, string field) = mixin(type.stringof ~ "." ~ 
 field ~ ".offsetof");

 To ensure that a syntactically valid symbol is passed as the 
 type.
Interestingly, but this code doesn't compile: enum offsetof(typenfield) = mixin(type.stringof ~ ".offsetof"); writeln(offsetof!(StrToBob.bob));
That's because `StrToBob.bob.stringof` is "bob". You can use this instead: import std.traits; enum offsetof(alias typenfield) = mixin(fullyQualifiedName!(typenfield) ~ ".offsetof");
May 06 2014
parent reply Artur Skawina via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
I'm not sure why you'd want to wrap the .offsetof expression in
a template, but it can easily be done like this:

   enum offsetOf(alias A, string S) = mixin("A."~S~".offsetof");


Keep in mind that D's offsetof is flawed - if the object does not
contain the requested member, but implicitly converts to another one
that does have such field then the expression compiles, but yields
a bogus value. Eg

   struct S { int a, b, c; S2 s2; alias s2 this; }
   struct S2 { int d, e; }
   static assert(S.e.offsetof==4); // Oops.

artur
May 06 2014
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Artur Skawina:

 Keep in mind that D's offsetof is flawed - if the object does 
 not contain the requested member, but implicitly converts to 
 another one that does have such field then the expression
 compiles, but yields a bogus value. Eg

    struct S { int a, b, c; S2 s2; alias s2 this; }
    struct S2 { int d, e; }
    static assert(S.e.offsetof==4); // Oops.
Is this in Bugzilla? Bye, bearophile
May 06 2014
prev sibling parent reply "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> writes:
On Tuesday, 6 May 2014 at 14:25:01 UTC, Artur Skawina via 
Digitalmars-d-learn wrote:
 I'm not sure why you'd want to wrap the .offsetof expression in
 a template, but it can easily be done like this:

    enum offsetOf(alias A, string S) = mixin("A."~S~".offsetof");
Great, that's even shorter. Somehow I was fixated on converting the symbol to a string first, but of course the name is directly available in the mixin: enum offsetof(alias typenfield) = mixin("typenfield.offsetof");
May 06 2014
parent reply Artur Skawina via Digitalmars-d-learn <digitalmars-d-learn puremagic.com> writes:
On 05/06/14 16:45, via Digitalmars-d-learn wrote:
 On Tuesday, 6 May 2014 at 14:25:01 UTC, Artur Skawina via Digitalmars-d-learn
wrote:
 I'm not sure why you'd want to wrap the .offsetof expression in
 a template, but it can easily be done like this:

    enum offsetOf(alias A, string S) = mixin("A."~S~".offsetof");
Great, that's even shorter. Somehow I was fixated on converting the symbol to a string first, but of course the name is directly available in the mixin: enum offsetof(alias typenfield) = mixin("typenfield.offsetof");
I didn't realize that worked, but it does. So... enum offsetOf(alias A) = A.offsetof; But I have no idea why anybody would want to wrap this trivial expression like that. And, I have no idea if the, hmm, /unconventional/ D offsetof semantics are in the bugzilla. It's not really a "bug", but a design mistake... artur
May 06 2014
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Artur Skawina:

 And, I have no idea if the, hmm, /unconventional/ D offsetof 
 semantics
 are in the bugzilla. It's not really a "bug", but a design 
 mistake...
Design mistakes are valid bugzilla entries. At worst the bad behavior could be documented. But often it's possible to fix the design too, with a small breaking change. Bye, bearophile
May 06 2014
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Artur Skawina:

 But I have no idea why anybody would want to wrap this trivial
 expression like that.

 And, I have no idea if the, hmm, /unconventional/ D offsetof 
 semantics
 are in the bugzilla. It's not really a "bug", but a design 
 mistake...
https://issues.dlang.org/show_bug.cgi?id=12714 Bye, bearophile
May 08 2014
prev sibling parent "Mengu" <mengukagan gmail.com> writes:
On Tuesday, 6 May 2014 at 15:13:41 UTC, Artur Skawina via 
Digitalmars-d-learn wrote:
 On 05/06/14 16:45, via Digitalmars-d-learn wrote:
 On Tuesday, 6 May 2014 at 14:25:01 UTC, Artur Skawina via 
 Digitalmars-d-learn wrote:
 I'm not sure why you'd want to wrap the .offsetof expression 
 in
 a template, but it can easily be done like this:

    enum offsetOf(alias A, string S) = 
 mixin("A."~S~".offsetof");
Great, that's even shorter. Somehow I was fixated on converting the symbol to a string first, but of course the name is directly available in the mixin: enum offsetof(alias typenfield) = mixin("typenfield.offsetof");
I didn't realize that worked, but it does. So... enum offsetOf(alias A) = A.offsetof; But I have no idea why anybody would want to wrap this trivial expression like that. And, I have no idea if the, hmm, /unconventional/ D offsetof semantics are in the bugzilla. It's not really a "bug", but a design mistake... artur
just out of curiousity, why an alias is used there?
May 08 2014
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Andrey:

 A similar D code is, as far as I know,

 type.field.offsetof
Yes, it's a built-in feature of D.
 Is there an any way to make a corresponding D template?
I don't understand. Please explain better. Bye, bearophile
May 05 2014
prev sibling parent reply "safety0ff" <safety0ff.dev gmail.com> writes:
On Monday, 5 May 2014 at 03:57:54 UTC, Andrey wrote:
 A similar D code is, as far as I know,

 type.field.offsetof

 Is there an any way to make a corresponding D template?
What you've written is the specific syntax for offsetof in D. If the intent is to create a template so that you can simply find/replace offsetof(type,field) with offsetoftemplate!(type,field) then I think it is easier to create a sed script - better yet a D program - for replacing the C macro with D code. Example program: import std.array; import std.file; import std.regex; import std.string; int main(string[] args) { if (args.length < 2) return -1; auto regex = ctRegex!(`offsetof\(([^,]+),([^)]+)\)`); auto sink = appender!(char[])(); foreach (filename; args[1..$]) { auto text = readText(filename); sink.reserve(text.length); replaceAllInto!(cap => cap[1].strip~"."~cap[2].strip~".offsetof")(sink, text, regex); write(filename, sink.data); sink.clear(); } return 0; }
May 05 2014
parent "Andrey" <none none.no> writes:
On Monday, 5 May 2014 at 09:04:29 UTC, safety0ff wrote:
 	auto regex = ctRegex!(`offsetof\(([^,]+),([^)]+)\)`);
 	auto sink = appender!(char[])();
 	foreach (filename; args[1..$])
 	{
 		auto text = readText(filename);
 		sink.reserve(text.length);
 		replaceAllInto!(cap => 
 cap[1].strip~"."~cap[2].strip~".offsetof")(sink, text, regex);
 		write(filename, sink.data);
 		sink.clear();
 	}
 	return 0;
 }
Cool!! Thank you!!!
May 05 2014