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);
}

Reply via email to