extern(C++) and struct (constness mangling problem ?)

deadalnix deadalnix at gmail.com
Wed Nov 30 02:48:58 PST 2011


Le 29/11/2011 23:06, Timon Gehr a écrit :
> On 11/29/2011 10:46 PM, deadalnix wrote:
>> Le 29/11/2011 22:09, Andrei Alexandrescu a écrit :
>>> On 11/29/11 11:39 AM, deadalnix wrote:
>>>> Le 29/11/2011 19:52, Andrei Alexandrescu a écrit :
>>>>> On 11/29/11 10:50 AM, deadalnix wrote:
>>>>>> 2/ Use that stract/class as a value type. You can do POD, but also
>>>>>> define constructor and destructor, copy constructor and overload
>>>>>> assignement. Anyway, you'll never be able to use proper polymorphism
>>>>>> here, because it would require virtual destructor at least. This is
>>>>>> IMO,
>>>>>> what D's struct should achieve.
>>>>>
>>>>> Yes.
>>>>>
>>>>>> The 2/ case is overly used in almost any C++ program. And D struct
>>>>>> should be able to match them. It wouldn't require much to make it
>>>>>> working :
>>>>>> - Default constructor.
>>>>>
>>>>> No.
>>>>>
>>>>
>>>> No, as "No it will never be done for reason xxx" or as in "No you are
>>>> wrong and it not necessary, here the way to do : xxx".
>>>>
>>>> In both cases, the xxx is the most interesting part :'(
>>>
>>> Neither :o). The default initializer that doesn't do any real "work",
>>> does not throw, and puts the object in a state without ex-situ ownership
>>> has brought D too many benefits to ignore.
>>>
>>> We should be able to define types that refuse default initialization (a
>>> la non-null pointers), but if the default initializer exists, it's good
>>> as it is.
>>>
>>>
>>> Andrei
>>>
>>
>> I do not question the benefit of initializer that don't do any real
>> "work" as you said. This is definitively a good thing.
>>
>> What I question, is the impossibility for the programmer to do another
>> way. This result in very convoluted way to interract with C++. The D
>> phylosophy is to enforce a clean and safe way to do thing (and default
>> initializer definitively goes in that direction) but also open the
>> possibility to get dirty and do whatever is required to do yout hanky
>> panky stuffs.
>>
>> Here is what I suggest :
>> - struct with no default constructor just behave the same way as the did
>> until now.
>> - struct can disable the default constructor as it is possible now. If
>> you create a variable of that type without initialization, you get an
>> error.
>> - struct can define a default constructor. You get the same errors as
>> you get when you disable that default constructor.
>>
>> With some code :
>> struct S {
>> // default constructor defined or disabled
>> }
>>
>> S s; // Error if the default constructor is defined or disabled;
>> S s = S(); // OK if you have a default constructor, error otherwize.
>> S s = S.init; // Call the postblit if a default constructor exists or is
>> disabled
>>
>> That way, we keep the benefit of default initializer for most struct,
>> but open the door for programmers that don't know what fear is about.
>>
>> This modify the behaviour of the struct, but, ATM, the default
>> constructor can be disabled, and it result in inconsistent behaviour
>> (exemple 1 generate error, exemple 3 compile fine and don't call
>> postblit).
>>
>> As the behaviour is different - we losse benefits of default
>> initializers -, we may want to explicit that with a keyword. As you
>> suggested, this is similar with non nullable references and could use
>> the same keyword (and this is a feature that is missing definitively,
>> null check is so easy to forget that it would be great that the compiler
>> help us in the task).
>>
>> This definitively have an impact on severals aspect of D (resising
>> arrays is a good exemple). Thoses would be impacted by the default
>> constructor caracteritics (eventually can throw, become exepensive in
>> computation, etc . . .). We may want to disable thoses operations on
>> such types or limit them in some ways.
>>
>> By the way, bug on opAssign is filled now.
>
> I think it is a reasonable request to allow S s = S(), because you can
> get the same with static opCall already (more inconvenient though, and
> no way to get it to work with extern(C++) structs).
>
> But I am not sure what to do about the
>
> S s = S.init;
>
> situation.
>
> Calling the postblit is just wrong, because there is no copying going
> on: S.init is constructed and then _moved_ into s. Move semantics are
> important, because it allows D code to translate to much faster code
> than C++98 code that always has to copy and destroy instead of moving.
>
>
>

That make sense. Then, the .init should be a property that call default 
constructor if it exists.

This anyway is important only of we have a default constrctor. Which 
isn't the idiomatic way in D. But, just as you can get pointer to 
elements of an array instead of using slice, you should be able to go 
where you are not supposed to :D


More information about the Digitalmars-d mailing list