Returning const ref (structs) in D
Dan
dbdavidson at yahoo.com
Sat Nov 24 14:22:18 PST 2012
On Saturday, 24 November 2012 at 22:01:32 UTC, Stian wrote:
> After reading that a couple of times it is a bit clearer, thank
> you. I need to wrap my head around this. I am working on a
> simple render/game engine, where, of course, vectors and
> matrices are flying around.
>
> Is the compiler sophisticated enough that is it able to avoid
> the copying. For instance, if i have a struct Matrix4x4 a =
> node.getTransformation() and use a for whatever, but never
> alter it, will it be able to avoid the copy? What if i declare
> it const or immutable? Do i have to use a pointer to it?
>
> After doing some small stuff in D I am not impressed by the
> mental mapping I am having with the memory system currently. I
> have some more experience with high performance programs in C++
> and appreciate the transparency of the memory management.
To add to Johnathan's answer, with some code. As he pointed out,
you can not have:
Bar nonConstBar = foo.bar;
as that would be trying to make a non-const copy of something
const with reference semantics. If that were allowed changes
could be made to nonConstBar that would affect foo.bar which is
const. If, however S had no pointers, dynamic arrays, associative
arrays or members with those types, there would be no reference
semantics and the copy of const into non-const would be fine
(i.e. no compile error would occur).
Similarly, as stated, there is no such thing as stack reference,
like this in C++:
S const& s = t.s;
So, I think you can still have what you want and are familiar
with, but you must distinguish at the point of assignment
whenever crossing the boundary from non-const to const (and the
reverse) for reference types. The way to do that is as you say,
get a deep copy, but something special is required to do the deep
copy:
(https://github.com/patefacio/d-help/blob/master/d-help/opmix/mix.d)
Thanks
Dan
---------------------
import std.stdio;
import std.traits;
import opmix.mix;
struct Bar {
private char[] c;
this(this) { c = c.dup; }
}
class Foo {
@property ref const(Bar) bar() const { return _bar; }
this(ref const(Bar) bar) { _bar = bar.gdup; }
private Bar _bar;
}
void moo(ref const(Bar) bar) {
writeln("foo => ", bar);
}
void main() {
Bar bar = { ['a','b'] };
auto foo = new Foo(bar);
moo(foo.bar);
// Following fails because Bar has reference semantics
// Compile error: conversion error from const(Bar) to Bar
// Bar nonConstBar = foo.bar;
// This works because gdup copies all fields recursively
Bar nonConstBar = foo.bar.gdup;
writeln(nonConstBar);
}
More information about the Digitalmars-d-learn
mailing list