www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Do I have to pass parameters with ref explicitly?

reply Elfstone <elfstone yeah.net> writes:
I'm reading some d-sources, and it looks like they pass big 
structs by value.
Such as:

     Matrix4x4f opBinary(string op)(Matrix4x4f rhs) { ... }

I came from a C++ background, and I would have written:

     Matrix4x4f opBinary(string op)(const ref Matrix4x4f rhs) { 
... }

I haven't found anything in the docs yet. Will the d-compiler 
optimize them into virtually the same? Can someone give me a 
reference?
Apr 16 2022
parent reply max haughton <maxhaton gmail.com> writes:
On Sunday, 17 April 2022 at 03:00:28 UTC, Elfstone wrote:
 I'm reading some d-sources, and it looks like they pass big 
 structs by value.
 Such as:

     Matrix4x4f opBinary(string op)(Matrix4x4f rhs) { ... }

 I came from a C++ background, and I would have written:

     Matrix4x4f opBinary(string op)(const ref Matrix4x4f rhs) { 
 ... }

 I haven't found anything in the docs yet. Will the d-compiler 
 optimize them into virtually the same? Can someone give me a 
 reference?
It's the same as C++.
Apr 16 2022
parent reply Elfstone <elfstone yeah.net> writes:
On Sunday, 17 April 2022 at 04:00:19 UTC, max haughton wrote:
 On Sunday, 17 April 2022 at 03:00:28 UTC, Elfstone wrote:
 I'm reading some d-sources, and it looks like they pass big 
 structs by value.
 Such as:

     Matrix4x4f opBinary(string op)(Matrix4x4f rhs) { ... }

 I came from a C++ background, and I would have written:

     Matrix4x4f opBinary(string op)(const ref Matrix4x4f rhs) { 
 ... }

 I haven't found anything in the docs yet. Will the d-compiler 
 optimize them into virtually the same? Can someone give me a 
 reference?
It's the same as C++.
In C++ I would expect the copy to be optimized away, even when passed by value. Do you mean d-compilers (optionally?) do the same optimization too?
Apr 16 2022
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 4/16/22 21:56, Elfstone wrote:
 On Sunday, 17 April 2022 at 04:00:19 UTC, max haughton wrote:
 On Sunday, 17 April 2022 at 03:00:28 UTC, Elfstone wrote:
 I'm reading some d-sources, and it looks like they pass big structs
 by value.
 Such as:

     Matrix4x4f opBinary(string op)(Matrix4x4f rhs) { ... }

 I came from a C++ background,
Me too. The situation is much simpler compared to C++: - Classes have no issues with copying at all because they are proper reference types. (I argue that classes (types used in OOP hierarchies) are reference types in C++ as well but in C++ the programmer must be careful to not pass class objects by value. (See the slicing problem.)) - Structs usually don't have issues with copying either because their copy is bit-level copying (blitting) by default. In D, structs are value types that should not have identities. It is illegal to have struct objects that refer to structs or their members by reference. They can be moved around at will. - The latter point happens all the time with rvalues: They are blitted around without copying anything. Still, the language had (and still has) the post-blit function to give the programmer a chance to fix things around when struct objects got blitted. Further still, some industry users (I think it was Weka.io) convinced the D community that it was impossible to implement certain idioms (was that reference-counting?) without proper copy constructors; so now D has copy constructors which are encouraged. (Post-blit are discouraged but they take precedence when both the post-blit and the copy constructor exist for a type.) - Somewhat related, unlike C++, D does not allow binding rvalues to 'const ref'. (This point is relevant for 'in' below.)
 and I would have written:

     Matrix4x4f opBinary(string op)(const ref Matrix4x4f rhs) { ... }
D has always had 'in' parameters but they were nothing other than the shorter syntax for 'const scope'. Now, when compiled with the -preview=in compiler command line switch, 'in' parameters relieve the programmer from some mental load on how to pass parameters. In D, if it is an input to a function, then mark it as 'in' and the compiler will do some magic: https://dlang.org/spec/function.html#in-params I call it magic because it allows passing rvalues as ref! (I think this obviates the "missing" feature of D that should allow binding rvalues to const ref. Well, who really needs it when we have -preview=in now?) It is further magical because 'in' does not pass types that have copy constructor, post-blit, or destructor by-value! Wow! So, this leaves only your concern of blitting big structs. I still don't know size of a struct should be considered big when the following two costs are compared: - Blitting bytes has a cost - Reaching members of structs (which 'const ref' would incur) through a pointer has a cost
 I haven't found anything in the docs yet. Will the d-compiler
 optimize them into virtually the same? Can someone give me a reference?
It's the same as C++.
In C++ I would expect the copy to be optimized away, even when passed by value. Do you mean d-compilers (optionally?) do the same optimization
too? You can expect at least the same optimizations for D because two major C++ and D compilers share the same backend: clang for C++ and ldc for D. Judging from how Walter Bright, the creator of D, has been a C++ compiler writer, to me it is hard to imagine that he would not make D at least as much capable as C++ when it comes to optimizations. However, dmd, the reference compiler, is known to be less capable in optimizing code from both from ldc and gdc (the gcc's D compiler). Ali
Apr 17 2022
next sibling parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 4/17/22 01:45, Ali Çehreli wrote:

 In D, if it
 is an input to a function, then mark it as 'in' and the compiler will do
 some magic:

    https://dlang.org/spec/function.html#in-params
I should have remembered that there are some improvements coming for -preview=in as reported by Mathias Lang and as relayed by Mike Parker here: https://forum.dlang.org/post/zfmkiqwkkexeaohjsuru forum.dlang.org Ali
Apr 17 2022
prev sibling parent Elfstone <elfstone yeah.net> writes:
Thanks Ali. That's a lot of information.
I'm learning D by rewriting my hobbyist project. I guess I can 
worry about optimization later.

On Sunday, 17 April 2022 at 08:45:11 UTC, Ali Çehreli wrote:
 - Somewhat related, unlike C++, D does not allow binding 
 rvalues to 'const ref'. (This point is relevant for 'in' below.)
Yeah, I just found out about that. It seems many things are done differently with D, but so far the code turns out to be a lot less clumsy than the C++ version. It's a good sign.
Apr 17 2022