Thread overview
.offsetof does not work as described dmd 0.131 (win32)
Sep 14, 2005
Klaus Oberhofer
Sep 14, 2005
zwang
Sep 14, 2005
Klaus Oberhofer
Sep 14, 2005
Regan Heath
Sep 15, 2005
Klaus Oberhofer
Sep 14, 2005
Klaus Oberhofer
Sep 14, 2005
Carlos Santander
September 14, 2005
class Foo
{
  int x;
}

void main()
{
  size_t o;
  o = Foo.x.offsetof;
}

This is more or less example code from the docs, but it does not compile:

foo.d(13): 'this' is only allowed in non-static member functions
foo.d(13): this for x needs to be type Foo not type int

September 14, 2005
Klaus Oberhofer wrote:
> class Foo
> {
>   int x;
> }
> 
> void main()
> {
>   size_t o;
>   o = Foo.x.offsetof;
> }
> 
> This is more or less example code from the docs, but it does not compile:
> 
> foo.d(13): 'this' is only allowed in non-static member functions
> foo.d(13): this for x needs to be type Foo not type int
> 

Perhaps you need to make a instance of Foo:

# class Foo
# {
#   int x;
# }
#
# void main()
# {
#   size_t o;
#   o = (new Foo).x.offsetof;
# }
September 14, 2005
Jari-Matti Mäkelä wrote:
> Klaus Oberhofer wrote:
> 
>> class Foo
>> {
>>   int x;
>> }
>>
>> void main()
>> {
>>   size_t o;
>>   o = Foo.x.offsetof;
>> }
>>
>> This is more or less example code from the docs, but it does not compile:
>>
>> foo.d(13): 'this' is only allowed in non-static member functions
>> foo.d(13): this for x needs to be type Foo not type int
>>
> 
> Perhaps you need to make a instance of Foo:
> 
> # class Foo
> # {
> #   int x;
> # }
> #
> # void main()
> # {
> #   size_t o;
> #   o = (new Foo).x.offsetof;
> # }

Or, use the following trick:

class Foo
{
  int x;
}

void main()
{
  size_t o;
  o = (cast(Foo)0).x.offsetof;
}
September 14, 2005
Thank you, this works. But in this case the docs are incorrect ? From the documentation:

------ snip -------
Field Properties

The .offsetof property gives the offset in bytes of the field from the beginning of the class instantiation. .offsetof can only be applied to fields qualified with the type of the class, not expressions which produce the type of the field itself:

	class Foo
	{
	    int x;
	}
	...
	void test(Foo foo)
	{
	    size_t o;

	    o = Foo.x.offsetof;   // yields 8
	    o = foo.x.offsetof;   // error, .offsetof an int type
	}
------ snip -------

September 14, 2005
BTW, the same sample with a struct instead of a class works as described:

struct Foo
{
  int x;
}

void main()
{
  size_t o;
  o = Foo.x.offsetof;
}
September 14, 2005
Klaus Oberhofer wrote:
> BTW, the same sample with a struct instead of a class works as described:
> 
> struct Foo {   int x;
> } 
> 
> void main()
> {
>   size_t o;
>   o = Foo.x.offsetof; }

Structs behave differently from classes. The problem in your previous post was that you only can refer to class members via a class instance. (cast(Foo)0) is an artificial instance via null pointer and (new Foo()) is trivially a new instance.
September 14, 2005
On Wed, 14 Sep 2005 14:38:14 +0000 (UTC), Klaus Oberhofer <oberhofer@ixxat.de> wrote:
> Thank you, this works. But in this case the docs are incorrect ?
> From the documentation:
>
> ------ snip -------
> Field Properties
>
> The .offsetof property gives the offset in bytes of the field from the
> beginning of the class instantiation. .offsetof can only be applied to
> fields qualified with the type of the class, not expressions which produce
> the type of the field itself:
>
> 	class Foo
> 	{
> 	    int x;
> 	}
> 	...
> 	void test(Foo foo)
> 	{
> 	    size_t o;
>
> 	    o = Foo.x.offsetof;   // yields 8
> 	    o = foo.x.offsetof;   // error, .offsetof an int type
> 	}
> ------ snip -------

I would have said that "foo.x" was an expression that produced a type i.e. int
I would have said that "Foo.x" was a field qualified with the type of the class.
In which case it is a bug or these docs are wrong for classes.

I would have expected class and structs to behave the same, that said they _are_ different and it is possible that the exact offsets of things are not known until the instance has been constructed? I wouldn't know IANACW (I am not a compiler writer)

Regan

September 14, 2005
Klaus Oberhofer escribió:
> class Foo
> {
>   int x;
> }
> 
> void main()
> {
>   size_t o;
>   o = Foo.x.offsetof;
> }
> 
> This is more or less example code from the docs, but it does not compile:
> 
> foo.d(13): 'this' is only allowed in non-static member functions
> foo.d(13): this for x needs to be type Foo not type int
> 

Foo.init.x.offsetof also works.

-- 
Carlos Santander Bernal
September 15, 2005
When I use the offsetof attribute inside a nonstatic method of the class it compiles:

class Foo
{
  int x;

  void bar()
  {
    size_t o;
    o = Foo.x.offsetof;
  }
}


void main()
{
  Foo f = new Foo;
  f.bar();
}

In my opinion the class layout will be fixed at some stage
in the compiler, and you should not need a this pointer to
determine the offset of a member relative to the
"beginning of the class instantiation".