digitalmars.D.learn - Why can't I copy a const struct?
- Atila Neves (16/16) Nov 15 2013 private struct DummyStruct {
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (25/40) Nov 15 2013 The short answer to the question in the subject line is because D does
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (7/11) Nov 15 2013 I lied! :) The type of a is int[] in there. The actual trouble is, to be...
- Atila Neves (9/13) Nov 16 2013 Ah, right. In D a copy is a move followed by a post-blit and the
private struct DummyStruct { int[] a; this(this) { a = a.dup; } } void main() { const dummy1 = DummyStruct(); DummyStruct dummy2 = dummy1; } struct_copy.d(12): Error: conversion error from const(DummyStruct) to DummyStruct Surely I should be able to copy it and use the mutable version as I please, no? I'd understand if the postblit constructor wasn't defined... Atila
Nov 15 2013
The short answer to the question in the subject line is because D does not have copy constructors. On 11/15/2013 07:12 AM, Atila Neves wrote:private struct DummyStruct { int[] a; this(this) { a = a.dup;That line can work only if a is mutable. The trouble is, the type of a is const(int[]) there.} } void main() { const dummy1 = DummyStruct(); DummyStruct dummy2 = dummy1; } struct_copy.d(12): Error: conversion error from const(DummyStruct) to DummyStruct Surely I should be able to copy it and use the mutable version as I please, no? I'd understand if the postblit constructor wasn't defined...That makes sense but the compiler would not analyze the code and ensure that the code obeys const. (It probably can in most situations though.)AtilaOne workaround is a constructor that takes by ref const: import std.stdio; private struct DummyStruct { int[] a; this (int[] a) { this.a = a.dup; } this(ref const(DummyStruct) that) { writeln("copy"); this.a = that.a.dup; } } void main() { const dummy1 = DummyStruct([ 1 ]); auto dummy2 = DummyStruct(dummy1); // <-- note different syntax assert(dummy2.a.ptr != dummy1.a.ptr); } Ali
Nov 15 2013
On 11/15/2013 10:37 AM, Ali Çehreli wrote:> this(this) { > a = a.dup; That line can work only if a is mutable. The trouble is, the type of a is const(int[]) there.I lied! :) The type of a is int[] in there. The actual trouble is, to be able to start executing this(this), the left-hand side a should have already been a reference to the right-hand side a. What fails is that initialization of the mutable reference on the left-hand side from the const reference on the right-hand side. Ali
Nov 15 2013
What fails is that initialization of the mutable reference on the left-hand side from the const reference on the right-hand side. AliAh, right. In D a copy is a move followed by a post-blit and the move fails because the source is const, got it. It's still silly, though. In theory the compiler could check the postblit constructor to see if it copies (I'm aware this might be easier said than done). In my case it'll mean that I'll have to drop const off of some methods because of this. And they really should be const... I hate to say it, but this is where const_cast would take care of the problem for me in C++.
Nov 16 2013