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

Robert burner Schadek realburner at gmx.de
Thu Jan 31 11:54:46 PST 2013


On 01/31/2013 08:34 PM, Dmitry Olshansky wrote:
> 31-Jan-2013 23:32, Maxim Fomin пишет:
>> On Thursday, 31 January 2013 at 19:17:56 UTC, Dmitry Olshansky wrote:
>>> 31-Jan-2013 19:21, Andrei Alexandrescu пишет:
>>>> On 1/31/13 10:18 AM, Steven Schveighoffer wrote:
>>>>> On Thu, 31 Jan 2013 10:12:53 -0500, Andrei Alexandrescu
>>>>>> 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
>>>>> ...
>>>>> }
>>>>
>>>> We could easily arrange things to segfault just the same with a
>>>> struct-based implementation.
>>>>
>>>
>>> Structs are quite borked in this regard e.g. without extra efforts the
>>> following:
>>>
>>> somclass aa = someclass();
>>> foor(aa, 1, 2); // segfault, surprize someclass() is someclass.init
>>>
>>> The current workaround I find the most sensible is:
>>> - @disable this();
>>> - make all constructors private
>>> - define opCall and forward it to private constructors. 0-arg versions
>>> have to pass dummy and/or default values to get struct constructed
>>>
>>> - automate this boilerplate until something in language is fixed? :)
>>>
>>> The advantage is that the following is illegal:
>>> someclass aa;
>>>
>>> and the following works as expected:
>>> auto aa = someclass(); //create empty container damn it!
>>
>> If desired default struct value is constant for all instances of that
>> struct, there is another workaround by changing init values:
>> -------------------
>> import std.stdio;
>>
>> class A { int x = 5; }
>>
>> struct S { int x = 5; A a; }
>>
>> void main()
>> {
>>      S s; // defaults to preallocated a, a is not null
>>      assert(S.x is 100 && s.a !is null && s.a.x is 100);
>> }
>
> This is fine except that it doesn't solve the problem of:
> Container a = Container(); //should be empty container, not illegal 
> null-container
Just use a payload struct and check whether that is null before every 
operation.
>
> Basically @dsiable this() is optional, but I like to help user avoid 
> bugs.
>
>>
>> import runtime;
>>
>> mixin(declareExternInitZPointer!S);
>>
>> static this()
>> {
>>      A a = new A;
>>      a.x = 100;
>>      S s =  S(100, a);
>>      rtSetDefaultHeapInitializer(s);
>>      rtSetDefaultStackInitializer(s, mixin(passExternInitZPointer!S));
>> }
>> ----------------------
>>
>> Where runtime module is http://dpaste.dzfl.pl/40b59a5d
>>
>> This does not fully replace default ctor, since all instances of S are
>> affected.
>
>



More information about the Digitalmars-d mailing list