www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Class Field Size/Offsets

reply "Maxime Chevalier" <maximechevalierb gmail.com> writes:
To access class fields in machine code generated by my JIT 
compiler, I need to be able to know the offset and size of the 
said fields. It seems that D requires a pointer to an instance of 
the class to make this work. This seems rather problematic for my 
usage.

Is it safe to circumvent this by using a null pointer or could I 
potentially get an exception/segfault by doing this? E.g.:

MyClass ptr = null;

auto fSize = ptr.theField.sizeof;
auto fOffs = ptr.theField.offsetof;

Is it safe to assume that the offset is the same in every 
instance? I would assume so (why would the offsets change?) but 
I'd like to know if the language actually guarantees this.
Mar 02 2013
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Maxime Chevalier:

 It seems that D requires a pointer to an instance of the class 
 to make this work.

I have related ER since a lot of time that has not received an answer in about three years: http://d.puremagic.com/issues/show_bug.cgi?id=3939 Bye, bearophile
Mar 02 2013
prev sibling next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 3/2/13, Maxime Chevalier <maximechevalierb gmail.com> wrote:
 To access class fields in machine code generated by my JIT
 compiler, I need to be able to know the offset and size of the
 said fields. It seems that D requires a pointer to an instance of
 the class to make this work.

Shouldn't the following work for you? class C { int a; int[4] b; } void main() { pragma(msg, C.a.sizeof); pragma(msg, C.a.offsetof); pragma(msg, C.b.sizeof); pragma(msg, C.b.offsetof); }
Mar 02 2013
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 3/2/2013 2:10 PM, Maxime Chevalier wrote:
 The problem persists without the mixin and the template:

It compiles without complaint for this code: -------------------------------------------- import std.stdio; class C { int a; } struct Foo { void foo() { auto sz = C.a.sizeof; writefln("sz: %s", sz); } } static this() { Foo f; f.foo(); } void main() { } -----------------------------------------
Mar 02 2013
parent Walter Bright <newshound2 digitalmars.com> writes:
On 3/2/2013 2:25 PM, Maxime Chevalier wrote:
 I'm guessing you use a bleeding edge version in which the bug has been fixed
 then. It doesn't work on DMD64 v2.062.

You're correct.
Mar 02 2013
prev sibling next sibling parent "Maxime Chevalier" <maximechevalierb gmail.com> writes:
Your example works but my use case doesn't and I have no idea why:

class C { int a; }

struct Foo
{
     void foo(string className, string fieldName)()
     {
         mixin("auto sz = " ~ className ~ "." ~ fieldName ~ 
".sizeof;");

         writefln("sz: %s", sz);
     }
}

static this()
{
     Foo f;

     f.foo!("C", "a");
}

Produces:

Error: this for a needs to be type C not type Foo
Error: template instance Foo.foo!("C", "a") error instantiating
Mar 02 2013
prev sibling next sibling parent "Maxime Chevalier" <maximechevalierb gmail.com> writes:
The problem persists without the mixin and the template:

class C { int a; }

struct Foo
{
     void foo()
     {
         auto sz = C.a.sizeof;
         writefln("sz: %s", sz);
     }
}

static this()
{
     Foo f;
     f.foo();
}

Error: this for a needs to be type C not type Foo
Mar 02 2013
prev sibling next sibling parent "Maxime Chevalier" <maximechevalierb gmail.com> writes:
I'm guessing you use a bleeding edge version in which the bug has 
been fixed then. It doesn't work on DMD64 v2.062.
Mar 02 2013
prev sibling next sibling parent "Peter Alexander" <peter.alexander.au gmail.com> writes:
On Saturday, 2 March 2013 at 22:25:24 UTC, Maxime Chevalier wrote:
 I'm guessing you use a bleeding edge version in which the bug 
 has been fixed then. It doesn't work on DMD64 v2.062.

Ditto: http://dpaste.dzfl.pl/8bf3cc73
Mar 02 2013
prev sibling next sibling parent "Andrej Mitrovic" <andrej.mitrovich gmail.com> writes:
On Saturday, 2 March 2013 at 22:10:57 UTC, Maxime Chevalier wrote:
 The problem persists without the mixin and the template:

 class C { int a; }

 struct Foo
 {
     void foo()
     {
         auto sz = C.a.sizeof;
         writefln("sz: %s", sz);
     }
 }

 static this()
 {
     Foo f;
     f.foo();
 }

 Error: this for a needs to be type C not type Foo

For 2.062 you're going to have to move the .sizeof expression outside of any methods which require 'this'. Make 'foo' static or wrap the .sizeof expression inside of a template and it will work. E.g.: template getSizeOf(alias symb) { enum getSizeOf = symb.sizeof; } struct Foo { void foo() { auto sz = getSizeOf!(C.a); writefln("sz: %s", sz); } } It's just a bug which will be fixed in the next version.
Mar 02 2013
prev sibling parent "Maxime Chevalier" <maximechevalierb gmail.com> writes:
Ok. I just got extra confused because in addition to the bug, 
this page: http://dlang.org/class.html (Field Properties section) 
seems to imply that C.a.sizeof isn't valid. Someone should 
probably update the page to reflect the proper behavior.
Mar 02 2013