www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - .offsetof does not work as described dmd 0.131 (win32)

reply Klaus Oberhofer <oberhofer ixxat.de> writes:
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
Sep 14 2005
next sibling parent reply =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= <jmjmak invalid_utu.fi> writes:
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; # }
Sep 14 2005
parent reply zwang <nehzgnaw gmail.com> writes:
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; }
Sep 14 2005
next sibling parent reply Klaus Oberhofer <oberhofer ixxat.de> writes:
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 -------
	
Sep 14 2005
parent reply "Regan Heath" <regan netwin.co.nz> writes:
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
Sep 14 2005
parent Klaus Oberhofer <oberhofer ixxat.de> writes:
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".
Sep 15 2005
prev sibling parent reply Klaus Oberhofer <oberhofer ixxat.de> writes:
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; 
}
Sep 14 2005
parent =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= <jmjmak invalid_utu.fi> writes:
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.
Sep 14 2005
prev sibling parent Carlos Santander <csantander619 gmail.com> writes:
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
Sep 14 2005