Const ref and rvalues again...

Timon Gehr timon.gehr at gmx.ch
Wed Nov 7 08:57:46 PST 2012


On 11/07/2012 04:01 PM, martin wrote:
> On Wednesday, 7 November 2012 at 10:33:03 UTC, Timon Gehr wrote:
>> You are still missing that const in C++ is different from const in D.
>> const in C++ does not mean anything. It is just loosely enforced
>> interface documentation. const in D actually restricts what the callee
>> can do with the argument, in a transitive fashion.
>
> I still don't get the big difference (except for transitiveness for
> pointers).

That is the main thing, but C++ also has a 'mutable' keyword.

> Given a const reference, I'm only able to invoke methods
> decorated with the const keyword (or inout in D) keyword, both in C++
> and D. And I can only pass it as argument by ref to functions which do
> not alter it (also taking a const reference, that is).
>

This is not the case in C++ for the D definition of 'not alter'.

>> Also, if the point is to have higher speed, why shouldn't the function
>> be allowed to use an rvalue as scratch space without a _deep copy_ ?
>
> I'm sorry but I don't get what you mean here. Could you please elaborate
> on this?
>

Well, if the changes are not visible, the function can freely change the 
memory in order to perform its computations.

>> When my struct does not support any operations that are const, and
>> creating a mutable copy is not possible due to indirections?
>
> If your struct doesn't support any const operations, it most likely has
> good reasons not to.
>

Either that, or someone hasn't bothered to annotate.

>> The change may well be visible...
>
> True in this case, but only if you know exactly what foo() does when you
> call it inside the main() function. And that is probably an indicator
> for bad encapsulation

The method is called 'foo', that means it is a toy example to show that 
the change may be visible. The change does not necessarily have to be 
visible to the caller directly.

> - most of the time, you shouldn't have the
> knowledge how foo() is exactly implemented when using it from the outside.

You got it exactly reverse. const harms encapsulation because it exposes 
some details about implementations. It is often not applicable in 
sufficiently dynamic code.


> It is clear that there are some examples where you want to pass an
> rvalue argument to a mutable ref parameter if you know exactly what the
> function does. But imo these cases are very rare and I don't really
> regard it as big issue if you need to add a line 'auto tmp = myRvalue;'
> before the function call to transform it to a referenceable lvalue, in
> these few cases.

You do not see issues with changing the interface based on 
implementation details?

> Much more commonly, you need a parameter just as read-only input.
> Consider a real-word-example of a 4x4 matrix consisting of 16 doubles
> (128 bytes). Most of the time, you'd only need a read-only input
> instance when working with it (combining matrices, transforming vectors
> etc.). Given its size (it's not really huge, I acknowledge that ;)), you
> probably want to avoid copying it around and therefore pass it by ref,
> but want that to also work for rvalues (produced by matrix combinations
> like 'viewMatrix * modelMatrix', for example).
>
> struct Matrix
> {
>      double[16] data;
>
>      // this op= other
>      ref Matrix opOpAssign(string op)(in ref Matrix other);
>
>      // Matrix result = this op other
>      Matrix opBinary(string op)(in ref Matrix other) const;
>
>      // double4 result = this * vector
>      // the vector (32 bytes) may be passed by value for AVX
>      double4 opBinary(string op)(in ref double4 vector) const
>          if (op == "*");
> };

I know your use case, and note that I do not have any issues with 
rvalues always being allowed to bind to ref parameters, which would 
solve your problem in all cases. (others do not like that though, which 
is why we have the current situation and your C++ - inspired design is 
discussed every second week or so.)



More information about the Digitalmars-d mailing list