pass-by-ref semantics for structs (was Deque impl.)

Steven Schveighoffer schveiguy at yahoo.com
Thu Jan 31 07:18:27 PST 2013


On Thu, 31 Jan 2013 10:12:53 -0500, Andrei Alexandrescu  
<SeeWebsiteForEmail at erdani.org> wrote:

> On 1/31/13 10:03 AM, Steven Schveighoffer wrote:
>> On Thu, 31 Jan 2013 07:27:08 -0500, d coder <dlang.coder at gmail.com>  
>> wrote:
>>
>>> On Thu, Jan 31, 2013 at 5:30 PM, monarch_dodra
>>> <monarchdodra at gmail.com> wrote:
>>>> The pull is kind of stuck in limbo, specifically because of the  
>>>> problems
>>>> associated with implementing reference semantics with structs :/
>>>
>>>
>>> Thanks for the enlightening email.
>>>
>>> I am of the considered view that reference semantics with structs in D
>>> is tough (if not impossible) with default constructor and postblit
>>> constructor (used when passing objects). This is because you can not
>>> initialize any object (wrapped in the struct) in the default
>>> constructor and if you are passing the struct as a function parameter,
>>> it is not possible to initialize these internal objects (before
>>> passing them) in the postblit constructor. I faced this in some of my
>>> code. Do not know if you are facing the same scenario in the DList
>>> implementation.
>>
>> It's pretty simple. Containers are reference types, and it makes most
>> sense to pass them by reference.
>>
>> In order to be sane, containers must be implemented as classes.
>> Otherwise, you have behavior like this:
>>
>> void foo(int[int] aa, int x, int y)
>> {
>> aa[x] = y;
>> }
>>
>> void main()
>> {
>> int[int] aa;
>> foo(aa, 1, 2);
>> aa[3] = 4;
>> foo(aa, 5, 6);
>> assert(!(1 in aa));
>> assert(aa[3] == 4);
>> assert(aa[5] == 6);
>> }
>>
>> In other words, the only way to turn a default-instantiated struct into
>> a valid struct is to use it once. Not the behavior you want.
>>
>> Classes don't have this problem, because you must instantiate them to
>> use them.
>
> As far as I can tell classes have the same problem.

Nope.

void foo(someclass aa, int x, int y)
{
    aa[x] = y;
}

void main()
{
    someclass aa;
    foo(aa, 1, 2); // segfault
    ...
}

-Steve


More information about the Digitalmars-d mailing list