www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Does D provide automatic dereferencing for accessing members through

reply "Gary Willoughby" <dev nomad.so> writes:
This is something that has been on my mind since i discovered 
this the other day. Does D provide automatic dereferencing for 
accessing members through pointers?

Here's an example:

import core.stdc.stdlib : malloc, free;

struct Foo
{
	public int bar;
}

void main(string[] args)
{
	auto foo = cast(Foo*)malloc(Foo.sizeof);

	foo.bar = 42;

	// Dereference the struct before accessing members.
	assert((*foo).bar == 42);

	// No dereferencing! eh?
	assert(foo.bar == 42);

	free(foo);
}

I've taken a look in the std lib and the second form is used a 
lot. Why don't you need to dereference the pointer 'foo' to reach 
its member 'bar'?
Aug 27 2014
next sibling parent reply "Brian Schott" <briancschott gmail.com> writes:
On Wednesday, 27 August 2014 at 19:25:42 UTC, Gary Willoughby 
wrote:
 Why don't you need to dereference the pointer 'foo' to reach 
 its member 'bar'?
The compiler inserts the dereference for you. (It knows which types are references and which are values and can do this correctly) This makes the syntax consistent between value and reference types.
Aug 27 2014
parent "Gary Willoughby" <dev nomad.so> writes:
On Wednesday, 27 August 2014 at 19:36:08 UTC, Brian Schott wrote:
 On Wednesday, 27 August 2014 at 19:25:42 UTC, Gary Willoughby 
 wrote:
 Why don't you need to dereference the pointer 'foo' to reach 
 its member 'bar'?
The compiler inserts the dereference for you. (It knows which types are references and which are values and can do this correctly) This makes the syntax consistent between value and reference types.
Awesome. Ta.
Aug 27 2014
prev sibling next sibling parent "Jesse Phillips" <Jesse.K.Phillips+D gmail.com> writes:
On Wednesday, 27 August 2014 at 19:25:42 UTC, Gary Willoughby 
wrote:
 I've taken a look in the std lib and the second form is used a 
 lot. Why don't you need to dereference the pointer 'foo' to 
 reach its member 'bar'?
Walter didn't want "foo->bar" so we have "foo.bar"
Aug 27 2014
prev sibling parent reply "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Wed, Aug 27, 2014 at 07:25:41PM +0000, Gary Willoughby via
Digitalmars-d-learn wrote:
 This is something that has been on my mind since i discovered this the
 other day. Does D provide automatic dereferencing for accessing
 members through pointers?
[...] Yes it does. This is particularly useful in generic code where you neither know (nor care) if the incoming type was a pointer or not; you can just use the dot notation and the compiler will do the Right Thing(tm). I remember trying to write C++ templates that will work for both pointer and non-pointer types -- it was rather painful due to the distinction between '.' and '->'. In D you just use '.' throughout and it Just Works(tm). T -- One reason that few people are aware there are programs running the internet is that they never crash in any significant way: the free software underlying the internet is reliable to the point of invisibility. -- Glyn Moody, from the article "Giving it all away"
Aug 27 2014
parent reply "Andrew Godfrey" <X y.com> writes:
On Friday, 29 August 2014 at 02:10:46 UTC, H. S. Teoh via 
Digitalmars-d-learn wrote:
 In D you just use '.' throughout and it Just > Works(tm).
Unless the property you're accessing is also a pointer property, like sizeof. Then you have to be careful. The below prints 4 then 8 (on 32-bit): unittest { import core.stdc.stdlib : malloc, free; struct Foo { public int bar, baz; } auto foo = cast(Foo*)malloc(Foo.sizeof); import std.stdio; writeln(foo.sizeof); writeln((*foo).sizeof); free(foo); } Do pointers have any other cases like this besides 'sizeof'? I couldn't find a list of pointer properties in the docs (whereas I know where the list of array properties is).
Aug 28 2014
next sibling parent reply "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Fri, Aug 29, 2014 at 04:37:37AM +0000, Andrew Godfrey via
Digitalmars-d-learn wrote:
 On Friday, 29 August 2014 at 02:10:46 UTC, H. S. Teoh via
 Digitalmars-d-learn wrote:
In D you just use '.' throughout and it Just Works(tm).
Unless the property you're accessing is also a pointer property, like sizeof. Then you have to be careful.
True. Though if you're writing generic code, chances are that what you want is the pointer size rather than the size of the referenced object. You only really get into trouble when you have to explicitly work with pointers. [...]
 Do pointers have any other cases like this besides 'sizeof'?
 I couldn't find a list of pointer properties in the docs (whereas I
 know where the list of array properties is).
Probably here? http://dlang.org/property.html T -- Time flies like an arrow. Fruit flies like a banana.
Aug 28 2014
parent reply "Andrew Godfrey" <X y.com> writes:
On Friday, 29 August 2014 at 05:05:55 UTC, H. S. Teoh via 
Digitalmars-d-learn wrote:
 On Fri, Aug 29, 2014 at 04:37:37AM +0000, Andrew Godfrey via 
 Digitalmars-d-learn wrote:
 Unless the property you're accessing is also a pointer 
 property, like
 sizeof. Then you have to be careful.
True. Though if you're writing generic code, chances are that what you want is the pointer size rather than the size of the referenced object. You only really get into trouble when you have to explicitly work with pointers.
Thanks for the link. 'sizeof' is not so bad anyway because it's a property of the type. It would be worse if pointers had properties. If you're insane enough to do the following, then this happens... struct Foo { int bar() { return 10; } } int bar(Foo f) { return 42; } int bar(Foo *f) { return 43; } int bar(Foo **f) { return 44; } unittest { Foo foo; auto pfoo = &foo; assert((*pfoo).bar == 10); assert(pfoo.bar == 10); auto ppfoo = &pfoo; assert(ppfoo.bar == 44); }
Aug 28 2014
parent "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Fri, Aug 29, 2014 at 05:28:12AM +0000, Andrew Godfrey via
Digitalmars-d-learn wrote:
 On Friday, 29 August 2014 at 05:05:55 UTC, H. S. Teoh via
 Digitalmars-d-learn wrote:
On Fri, Aug 29, 2014 at 04:37:37AM +0000, Andrew Godfrey via
Digitalmars-d-learn wrote:
Unless the property you're accessing is also a pointer property,
like sizeof. Then you have to be careful.
True. Though if you're writing generic code, chances are that what you want is the pointer size rather than the size of the referenced object. You only really get into trouble when you have to explicitly work with pointers.
Thanks for the link. 'sizeof' is not so bad anyway because it's a property of the type. It would be worse if pointers had properties.
[...] Which *could* happen if you use alias this, which is a common tool for implementing transparent (or, in this case, not-so-transparent) type wrappers: struct SmartPtr(T) { T* _impl; alias _impl this; property dumbProperty() { return 1; } } struct MyObj { int dumbProperty = 2; } void func(T)(T t) { assert(t.dumbProperty == 2); // will fail } func(SmartPtr!MyObj.init); // oops T -- BREAKFAST.COM halted...Cereal Port Not Responding. -- YHL
Aug 28 2014
prev sibling parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 08/28/2014 09:37 PM, Andrew Godfrey wrote:

 On Friday, 29 August 2014 at 02:10:46 UTC, H. S. Teoh via
 Digitalmars-d-learn wrote:
 In D you just use '.' throughout and it Just > Works(tm).
Unless the property you're accessing is also a pointer property, like sizeof. Then you have to be careful.
The same applies to class variables. .sizeof and .alignof operate on the class variable. To get the object's size and alignment, one needs to reach for classInstanceSize and classInstanceAlignment. Unfortunately, for historical reasons they have dissimilar syntax: import std.string; class C { ubyte[42] a; } void main() { auto c = new C(); pragma(msg, format("size : %s vs %s", c.sizeof, __traits(classInstanceSize, C))); import std.traits; pragma(msg, format("alignment: %s vs %s", c.alignof, classInstanceAlignment!C)); } Ali
Aug 28 2014