pointers, functions, and uniform call syntax

Carl Sturtivant sturtivant at gmail.com
Mon Sep 3 14:19:07 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 thought "this should have zero impact, because in D, because 
> "." is supposed to deference for you if needed."
>
> I find it strange though that when trying to call a function 
> with a pointer, the pointer isn't automatically dereferenced if 
> needed:
>
> ----
> struct S
> {
>   void foo();
> }
> void bar(S);
> void main()
> {
>   auto r = new S;
>   r.foo();
>   bar(r);  //derp
>   r.bar(); //derp
> };
> ----
> I find it strange, because I thought the entire point was to 
> abstract way something was allocated to the way it was used: 
> EG. From a caller perspective, I don't care if r is on the 
> stack or on the heap: I just want to call the method bar on the 
> object in question.
>
> Why does one consider a "free standing" function more ambiguous 
> than a member function?
>
> Things get even stranger if you mix in uniform call syntax. 
> "r.foo()" works, but "r.bar()" doesn't?
>
> Am I really forced into:
> ----
> struct S
> {
>   void foo();
> }
> void bar(S);
> void main()
> {
>   auto r = new S;
>   r.foo();
>   bar(*r);    //Groan
>   (*r).bar(); //Super Groan.
> };
> ----
> I feel as if I'm just back at square 1...

In a nutshell, I think you're broadly saying that you want to 
program with a struct S the same way whether it's stack or heap 
allocated. (Good code reuse, and no duplication of semantics with 
-> as in C++.) From this perspective the trouble is that "S()" 
and "new S()" don't have the same effect except for allocating 
one on the stack and one on the heap, and the language forbids 
you from overcoming this via reference variables, except by 
calling a function and passing "*r" to a "ref S" parameter.

So maybe that's what you should do with D in its present state. 
Once you've passed *r to the real main function for working with 
your big struct as "ref S", well, after that in all calls it's in 
value form.

It's useful that "new S()" produces a pointer when building low 
level data structures in D, and your purpose is to 
heap-rather-than-stack allocate and proceed as before. These are 
completely different purposes.

So I'm wondering if a language extension along the following 
lines would solve your problem, simply asking the compiler to use 
heap allocation when the variable is declared, e.g.

  @heap auto s = S(); //secretly allocated with new, but used as 
if local

where the compiler would know that s is valid, just as in a 
normal declaration. And the compiler would automatically 
deallocate the variable's heap storage when it goes out of scope. 
Otherwise the variable would behave like a normal local variable 
as far as inference of any kind made by the compiler in a wider 
context goes.




More information about the Digitalmars-d mailing list