www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Problems with D const ref vs C++ const &

reply "Craig Black" <craigblack2 cox.net> writes:
In C++ I could to the following:

Vector3 cross(const Vector3 &a, const Vector3 &b) { ... }

and then call it like this:

Vector3 a, b, c;
a = cross(b, c);
a = cross(b-a, c-a);

But in D I have to define two functions if I want pass by reference to work:

Vector3 cross(ref const Vector3 a, ref const Vector3 b) {...}
Vector3 cross(Vector3 a, Vector3 b) {...}

Not having an l-value forces me to pass by value, and I have to define two 
functions.  I know about auto ref but that only works for templates, and the 
compiler generates two functions which could lead to code bloat if the 
function is a big one.

-Craig
Dec 10 2010
next sibling parent "Craig Black" <craigblack2 cox.net> writes:
Just skimmed over the relevant discussion "Destructors, const structs, and 
opEquals".

So was a final solution ever agreed upon?  If so, has Walter agreed to 
implement the solution?

-Craig
Dec 10 2010
prev sibling next sibling parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/10/10 9:48 AM, Craig Black wrote:
 In C++ I could to the following:

 Vector3 cross(const Vector3 &a, const Vector3 &b) { ... }

 and then call it like this:

 Vector3 a, b, c;
 a = cross(b, c);
 a = cross(b-a, c-a);

 But in D I have to define two functions if I want pass by reference to
 work:

 Vector3 cross(ref const Vector3 a, ref const Vector3 b) {...}
 Vector3 cross(Vector3 a, Vector3 b) {...}

 Not having an l-value forces me to pass by value, and I have to define
 two functions. I know about auto ref but that only works for templates,
 and the compiler generates two functions which could lead to code bloat
 if the function is a big one.

 -Craig

auto ref should work for non-templates and generate only one function. The current implementation of auto ref originates in a misunderstanding. Andrei
Dec 10 2010
parent reply "Craig Black" <craigblack2 cox.net> writes:
 auto ref should work for non-templates and generate only one function. The 
 current implementation of auto ref originates in a misunderstanding.


 Andrei

Thanks for the response. I assume Walter is aware of this problem? What are the chances that this gets fixed soon? -Craig
Dec 10 2010
parent reply Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 12/10/10 12:47 PM, Craig Black wrote:
 auto ref should work for non-templates and generate only one function.
 The current implementation of auto ref originates in a misunderstanding.


 Andrei

Thanks for the response. I assume Walter is aware of this problem? What are the chances that this gets fixed soon?

There are various pressures on Walter's and Don's time, but generally the problems that cause people pain are more discussed around here and tend to be looked at sooner. Andrei
Dec 10 2010
parent reply Don <nospam nospam.com> writes:
Andrei Alexandrescu wrote:
 On 12/10/10 12:47 PM, Craig Black wrote:
 auto ref should work for non-templates and generate only one function.
 The current implementation of auto ref originates in a misunderstanding.


 Andrei

Thanks for the response. I assume Walter is aware of this problem? What are the chances that this gets fixed soon?

There are various pressures on Walter's and Don's time, but generally the problems that cause people pain are more discussed around here and tend to be looked at sooner. Andrei

It didn't seem to me that there was a convincing outcome from that discussion. We need an actual spec! (I only fix bugs. I don't make language decisions). In my opinion, the signature of opEquals is a litmus test for the const system. If it's elegant, we've struck gold. If it isn't, we've still got work to do.
Dec 10 2010
parent "Craig Black" <craigblack2 cox.net> writes:
"Don" <nospam nospam.com> wrote in message 
news:idu7km$5ea$1 digitalmars.com...
 Andrei Alexandrescu wrote:
 On 12/10/10 12:47 PM, Craig Black wrote:
 auto ref should work for non-templates and generate only one function.
 The current implementation of auto ref originates in a 
 misunderstanding.


 Andrei

Thanks for the response. I assume Walter is aware of this problem? What are the chances that this gets fixed soon?

There are various pressures on Walter's and Don's time, but generally the problems that cause people pain are more discussed around here and tend to be looked at sooner. Andrei

It didn't seem to me that there was a convincing outcome from that discussion. We need an actual spec! (I only fix bugs. I don't make language decisions). In my opinion, the signature of opEquals is a litmus test for the const system. If it's elegant, we've struck gold. If it isn't, we've still got work to do.

It seems to me that opEquals would work fine if the non-template auto ref was used. As Andrei described it, it should only generate one version of the function, and all parameters, including temporaries, should be passed by reference. But maybe I misunderstood Andrei or maybe I missed some caveat with opEquals? -Craig
Dec 10 2010
prev sibling next sibling parent reply Piotr Szturmaj <gacek999 tlen.nospam.pl> writes:
Craig Black wrote:
 In C++ I could to the following:

 Vector3 cross(const Vector3 &a, const Vector3 &b) { ... }

 and then call it like this:

 Vector3 a, b, c;
 a = cross(b, c);
 a = cross(b-a, c-a);

 But in D I have to define two functions if I want pass by reference to
 work:

 Vector3 cross(ref const Vector3 a, ref const Vector3 b) {...}
 Vector3 cross(Vector3 a, Vector3 b) {...}

Isn't const for that (without ref)? Vector3 cross(const Vector3 a, const Vector3 b) {...} In this case, compiler should pass const by reference (since it will not change).
Dec 10 2010
parent reply Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, December 10, 2010 14:31:34 Piotr Szturmaj wrote:
 Craig Black wrote:
 In C++ I could to the following:
 
 Vector3 cross(const Vector3 &a, const Vector3 &b) { ... }
 
 and then call it like this:
 
 Vector3 a, b, c;
 a = cross(b, c);
 a = cross(b-a, c-a);
 
 But in D I have to define two functions if I want pass by reference to
 work:
 
 Vector3 cross(ref const Vector3 a, ref const Vector3 b) {...}
 Vector3 cross(Vector3 a, Vector3 b) {...}

Isn't const for that (without ref)? Vector3 cross(const Vector3 a, const Vector3 b) {...} In this case, compiler should pass const by reference (since it will not change).

The compiler doesn't just make things references. You have to tell it to. If you have a const parameter which is a value type, it's just going to be a const local variable. It's not going to be a reference to anything no matter what that means for efficiency (though structs are supposedly supposed to be cheap to copy). Now, if Vector3 were a class, then it's always a reference. But that's because it's a reference type. - Jonathan M Davis
Dec 10 2010
parent Piotr Szturmaj <gacek999 tlen.nospam.pl> writes:
Jonathan M Davis wrote:
 On Friday, December 10, 2010 14:31:34 Piotr Szturmaj wrote:
 Craig Black wrote:
 In C++ I could to the following:

 Vector3 cross(const Vector3&a, const Vector3&b) { ... }

 and then call it like this:

 Vector3 a, b, c;
 a = cross(b, c);
 a = cross(b-a, c-a);

 But in D I have to define two functions if I want pass by reference to
 work:

 Vector3 cross(ref const Vector3 a, ref const Vector3 b) {...}
 Vector3 cross(Vector3 a, Vector3 b) {...}

Isn't const for that (without ref)? Vector3 cross(const Vector3 a, const Vector3 b) {...} In this case, compiler should pass const by reference (since it will not change).

The compiler doesn't just make things references. You have to tell it to. If you have a const parameter which is a value type, it's just going to be a const local variable. It's not going to be a reference to anything no matter what that means for efficiency (though structs are supposedly supposed to be cheap to copy). Now, if Vector3 were a class, then it's always a reference. But that's because it's a reference type. - Jonathan M Davis

Thank you for your explanations, I'm just learning D2. However, I meant something different: passing by reference was not strict ref in my mind, but some kind of address passing. This is done in Pascal/Delphi for more than decade. Variables passed as const parameters, are passed by address, to improve efficency, even if they're value types. Of course smaller builtin types like 32 bit integer doesn't get much advance. Const is supposed to be used with Vector3-like structs with floating point coordinates (12 bytes float, 24 bytes double), where it's better to not copy. Feel free to read first answer to this post: http://stackoverflow.com/questions/1600991/are-there-any-advantages-in-using-const-parameters-with-an-ordinal-type Question is, if const parameters works similarly in D2?
Dec 10 2010
prev sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On Friday, December 10, 2010 15:07:53 Piotr Szturmaj wrote:
 Jonathan M Davis wrote:
 On Friday, December 10, 2010 14:31:34 Piotr Szturmaj wrote:
 Craig Black wrote:
 In C++ I could to the following:
 
 Vector3 cross(const Vector3&a, const Vector3&b) { ... }
 
 and then call it like this:
 
 Vector3 a, b, c;
 a = cross(b, c);
 a = cross(b-a, c-a);
 
 But in D I have to define two functions if I want pass by reference to
 work:
 
 Vector3 cross(ref const Vector3 a, ref const Vector3 b) {...}
 Vector3 cross(Vector3 a, Vector3 b) {...}

Isn't const for that (without ref)? Vector3 cross(const Vector3 a, const Vector3 b) {...} In this case, compiler should pass const by reference (since it will not change).

The compiler doesn't just make things references. You have to tell it to. If you have a const parameter which is a value type, it's just going to be a const local variable. It's not going to be a reference to anything no matter what that means for efficiency (though structs are supposedly supposed to be cheap to copy). Now, if Vector3 were a class, then it's always a reference. But that's because it's a reference type. - Jonathan M Davis

Thank you for your explanations, I'm just learning D2. However, I meant something different: passing by reference was not strict ref in my mind, but some kind of address passing. This is done in Pascal/Delphi for more than decade. Variables passed as const parameters, are passed by address, to improve efficency, even if they're value types. Of course smaller builtin types like 32 bit integer doesn't get much advance. Const is supposed to be used with Vector3-like structs with floating point coordinates (12 bytes float, 24 bytes double), where it's better to not copy. Feel free to read first answer to this post: http://stackoverflow.com/questions/1600991/are-there-any-advantages-in-usin g-const-parameters-with-an-ordinal-type Question is, if const parameters works similarly in D2?

I'm pretty sure that they don't, but someone more familiar with the compiler would have to say. I'm sure that it wouldn't be for shared variables (those would _have_ to be copied or it would change semantics), but I could see how that might be possible to do under the hood by the compiler for normal variables. I don't think that dmd does that though. - Jonathan M Davis
Dec 10 2010