pointers, functions, and uniform call syntax

monarch_dodra monarchdodra at gmail.com
Wed Sep 5 01:49:56 PDT 2012


On Monday, 3 September 2012 at 12:12:46 UTC, monarch_dodra wrote:
> I was playing around with a very big struct, and told myself I 
> wanted it allocated on the heap. This meant I was now 
> manipulating S* instead of an S.

I've been extensively trying things out since I first posted 
this. I'd like to give some feedback:

-------------------------------------
First off, working with an S* has been a complete failure. The 
structure I was working with is several K. The problem is that 
come the first function call, my pointer is dereferenced and 
passed by value to the function, and then everything grinds to a 
halt.

The approach works well in C++, because everything is passed by 
reference. D, on the other hand, which promotes *not* having copy 
constructors, also promotes pass-by-value, which is completely 
incompatible. I like D's approach, but it also means having to 
shift the way I design my patterns.

-------------------------------------
The conclusion here is that the pointer must indeed be wrapped in 
some sort of structure, that has cheap copy. Things like 
RefCounted are actually *OK*, but as I was trying to write a 
"Reference" wrapper, I realized both have one *Major* flaw: 
Calling functions that return new objects, such as dup, save, 
opBinary etc... will leak the new object out of the 
"ReferenceType Wrapper" :/

On the other hand, I took my original S structure, and re-built 
it with an internal "Payload", and gave it reference semantics. 
*THAT* worked like a *CHARM* !!!

-------------------------------------
Regarding the first Enhancement Request, I know think it is a 
"Bad Idea ®" : Not because of any null pointer problems (IMO, 
that is actually a non-issue), but because of the implicit cast 
from S* to S. The thing with member functions is that they 
_Truly_Do_ take a pointer. The operator "." is not actually a 
"convenience dereference". When you think about it, it is 
actually the [(*p).member|p->member] syntax which is strange (All 
the way back to C, yes): why reference an object, if behind the 
scenes, all you do is pass the address?

I mean:

struct S
{
     void foo();
}
void bar(S* p);

void main()
{
     S* p = new S;
     p.foo();
     p.bar();
     S s;
     (&s).foo();
     (&s).bar();
}

When you think about, *that* makes a lot of sense (to me), and 
UFCS works correctly with it.



More information about the Digitalmars-d mailing list