No we should not support enum types derived from strings
12345swordy
alexanderheistermann at gmail.com
Wed May 12 01:58:39 UTC 2021
On Wednesday, 12 May 2021 at 01:46:25 UTC, deadalnix wrote:
> On Tuesday, 11 May 2021 at 21:36:46 UTC, Andrei Alexandrescu
> wrote:
>> Values are monomorphic. Years ago I found a bug in a large C++
>> system that went like this:
>>
>> class Widget : BaseWidget {
>> ...
>> Widget* clone() {
>> assert(typeid(this) == typeid(Widget*));
>> return new Widget(*this);
>> }
>> };
>>
>> The assert was a _monomorphism test_, i.e. it made sure that
>> the current object is actually a Widget and not something
>> derived from it, who forgot to override clone() once again.
>>
>> The problem was the code was doing exactly what it shouldn't
>> have, yet the assert was puzzlingly passing. Since everyone
>> here is great at teaching basic type theory, it's an obvious
>> problem - the fix is:
>>
>> assert(typeid(*this) == typeid(Widget));
>>
>> Then the assertion started failing as expected. Following
>> that, I've used that example for years in teaching and to
>> invariably there are eyes going wide when they hear that C++
>> pointers are monomorphic, it's the pointed-to values that are
>> polymorphic, and that's an essential distinction. (In D, just
>> like in Java, classes take care of that indirection
>> automatically, which can get some confused.)
>
> While this is indeed very interesting, this is missing the
> larger point.
>
> This whole model in C++ is unsound. It's easy to show. In you
> above example, the this pointer, typed as Widget*, points to an
> instance of a subclass of Widget. If you were to assign a
> Widget to that pointer (which you can do, this is a pointer to
> a mutable widget), then any references to that widget using a
> subtype of Widget is now invalid.
>
> There is no such thing as a monomorphic pointer to a
> polymorphic type in any sound type system. That cannot be made
> to work. It is unsound. This is why in Java or C#, the type
> represent both the pointer and the pointed data, as a package,
> being half a value, half a reference type in the process. This
> is unavoidable, you can't unbundle it or everything breaks down.
>
> So why is there an indirection in there? Simply because you
> cannot know the layout of the object at compile time when you
> are doing runtime polymorphism. But even then, you could decide
> to make it behave as a value type with eager deep copy or copy
> on write and that would work too, and it would still be
> polymorphic.
>
> D is correct to use Java and C# 's model. C++'s is unsound.
>
> But we get back to square one: this has nothing to do with the
> indirection. In fact, in the Java/C# model, class types are
> value type, which hold a reference to a payload. And the whole
> typing and subtyping business happen on these value types.
No, classes are reference types, structs are values types in c#.
-Alex
More information about the Digitalmars-d
mailing list