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

Timon Gehr timon.gehr at gmx.ch
Tue Nov 29 14:06:37 PST 2011


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.





More information about the Digitalmars-d mailing list