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