Code security: "auto" / Reason for errors

John Nixon via Digitalmars-d digitalmars-d at puremagic.com
Wed Jun 1 07:52:29 PDT 2016


On Wednesday, 2 March 2016 at 21:37:56 UTC, Steven Schveighoffer 
wrote:

> Pointer copying is inherent in D. Everything is done at the 
> "head", deep copies are never implicit. This is a C-like 
> language, so one must expect this kind of behavior and plan for 
> it.

I sympathise with Ozan. What is the best reference you know that 
explains this fully?

Clearly from your comments, we have lost the argument as far as D 
is concerned. This leads me to question whether a computer 
language that is similar to D except that all variables of any 
type are considered in the same way as objects that own their own 
data has been considered? I would like to suggest the following:
1. Assignment would imply full (deep) copies
2. “dup” functions would not need to exist
3. I think the const system could be much simpler, perhaps more 
like it is in C++
4. Function parameters would be passed by reference by default 
(to avoid unnecessary copying, but with a reliable const system)

I realise that copying large objects might then happen in 
erroneous code when not intended, but it would be easy for the 
programmer to diagnose this.

I raised a similar issue with the following program that was 
being discussed in the Learn forum for D and works correctly. 
Adding another writeln statement shows that the second line of 
test_fun calls first CS.this then CS.opAssign. An alternative 
version using a .dup function also works.

import std.stdio;

struct CS {
     char[] t;
     this(const CS rhs) {
         this = rhs;
     }
     CS opAssign(const CS rhs) {
         writeln("CS.opAssign called");
         this.t = rhs.t.dup;
         return this;
     }
};

void test_fun(const ref CS rhs) {
     auto cs = CS(rhs);
     writeln("cs = ",cs);
}

void main() {
     CS rhs;
     rhs.t = "string".dup;
     test_fun(rhs);
     return;
}

I wanted to be able to write instead simply:

struct CS {
     char[] t;
};

void test_fun(const ref CS rhs) {
     auto cs = rhs;
     writeln("cs = ",cs);
}

void main() {
     CS rhs;
     rhs.t = "string".dup;
     test_fun(rhs);
     return;
}

i.e. the functions this and opAssign aren’t needed, and the 
simple definition/assignment “auto cs = rhs;” would carry out the 
full copying of the CS object (as is the case for the simplest of 
D’s fundamental types). This would guarantee that rhs could not 
be changed in test_fun and allow it to be declared const. It 
seems to me there would be great advantages in the simpler syntax 
(especially if CS had many other members).

I think shallow copying at any level should not be the default 
especially as in general there would be a level of copying that 
needs specification i.e. how many pointers to de-reference e.g. 
if some elements were obtained by multiple indirection e.g. an 
array of arrays of char , char [][], where each array is dynamic.


More information about the Digitalmars-d mailing list