June 13, 2019
On Thursday, 13 June 2019 at 09:44:12 UTC, Vladimir Panteleev wrote:
> On Thursday, 13 June 2019 at 05:31:23 UTC, Walter Bright wrote:
>> On 6/11/2019 3:02 AM, Vladimir Panteleev wrote:
>>> [...]
>>
>> Ok, you got me there.
>>
>> Here's what Stroustrup says:
>>
>> http://www.stroustrup.com/bs_faq2.html#sizeof-empty
>
> From the page:
>
> 		Empty a, b;
> 		if (&a == &b) cout << "impossible: report error to compiler supplier";
>
> However, no further justification is provided why that is a problem.
>
> Perhaps it's something the C++ spec was written to guarantee, but does not apply to D?

Just for amusement, rust has ZSTs (zero sized types) and Empty types (they distinguish between the two) - https://doc.rust-lang.org/nomicon/exotic-sizes.html#zero-sized-types-zsts

And here's a consequence of that: https://github.com/rust-lang/rust/blob/e011fe1c132010e261cc9ea658da73152f1f7fc7/src/liballoc/vec.rs#L2428

Here's a more detailed "beware of these guys" https://gankro.github.io/blah/only-in-rust/#honorable-mention-zero-sized-types-zsts

"However, in low level (unsafe) code zero-sized types can be a bit hazardous, for two reasons:

If you try to malloc some number of zero-sized types naively, you'll pass an allocation size of 0 to the allocator, which is implementation-defined at best. Also you want to avoid allocating these things anyway!

If you try to offset a pointer to a zero-sized type naively, you will get nowhere. This breaks a C-style "two pointers moving towards each other" iterator."

Swift and go are also mentioned in the above link.

Cheers,
- Ali
June 13, 2019
On Thursday, 13 June 2019 at 10:25:02 UTC, aliak wrote:
> If you try to malloc some number of zero-sized types naively, you'll pass an allocation size of 0 to the allocator, which is implementation-defined at best. Also you want to avoid allocating these things anyway!

On 64 bit architectures you probably could write a custom malloc that will return a unique address outside the memory map for 0-sized allocations. It would have to mark it in a bitmap so that it could be freed.

*shrugs*

But, I doubt that people actually do this often. Allocating 4-8 bytes probably would be ok, so you could just redefine malloc as malloc(max(allocationsize,8)).


June 13, 2019
On 13.06.19 08:43, Manu wrote:
> What are we so afraid of? I don't understand the resistance to this
> *at all*...

I think a lot of the default opposition to new features (especially if they can be implemented with a moderate amount of user code) is about DMD compiler complexity, about adding new things to a code base which already suffers quite a bit from incidental complexity. (E.g., I learned last week that there are multiple different ways to infer function attributes. Some of them are quite broken, but I wasn't able to get rid of the special and broken `pure` inference without breaking the test suite, within the allotted time.)

> people talk about slicing, which is a pretty worthless
> baseline argument; it's totally possible in C++ and I've never heard a
> single case of anyone ever having that problem in my life, at work, at
> home, or even on the internet (yes, I'm sure I would find if I
> deliberately went looking). I'm only aware the concept has a name
> because I've seen it written in a book somewhere. It's 99.9999%
> not-even-remotely-a-problem, it's only a 'theoretical' problem.
> ...

Slicing is only a problem if you have a vtable.
June 13, 2019
On Thursday, 13 June 2019 at 10:25:02 UTC, aliak wrote:
> Here's a more detailed "beware of these guys" https://gankro.github.io/blah/only-in-rust/#honorable-mention-zero-sized-types-zsts
>
> "However, in low level (unsafe) code zero-sized types can be a bit hazardous, for two reasons:
>
> If you try to malloc some number of zero-sized types naively, you'll pass an allocation size of 0 to the allocator, which is implementation-defined at best. Also you want to avoid allocating these things anyway!
>
Especially if you use C allocation realloc() as calling it with size 0 is synonymous to free(). Ouch!

June 13, 2019
On Thursday, 13 June 2019 at 06:43:44 UTC, Manu wrote:
> This should obviously be a compile error:
>   struct A { int x; }
>   struct B : A { int y; }
>   B b;
>   A a = b; // <- obviously an error


It doesn't become so obvious when you can implicitly convert to the base type.

    A foo(ref A a) { return a; }

    B b;
    A a = foo(b);
June 13, 2019
On Thursday, 13 June 2019 at 07:04:06 UTC, Manu wrote:
> On Wed, Jun 12, 2019 at 11:40 PM Andrei Alexandrescu via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>>
>> On 6/11/19 7:45 PM, Manu wrote:
>> > On Tue, Jun 11, 2019 at 12:35 PM Exil via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>> >> Kind of curious, what do you use a base class for that has no members, is a size of zero, and also has no vtable or virtual functions?
>> >
>> > Metaprogramming; it's a template argument.
>>
>> Subtyping is not needed for metaprogramming. (C++'s awkward way of doing
>> it overuses it.)
>
> Overuse of `alias this` is not any better. `alias this` is relatively
> much more awkward, and I would say objectively less easy to read and
> understand.
> You can't miss the base at the top of the struct, you know exactly
> where to look for it. With `alias this`, you have to scan the object
> from top to bottom to see if it's there, and then you have to take
> note what object is acting as the base and look for that and where it
> sits relative to other members, and then worry about the zero-size
> hack.
> That alone makes C++'s "awkward way of doing it" look golden, but then
> there's also the issues with the IDE tooling, and that there's only
> one `alias this` slot, which we might need for implicit conversion of
> some sort.
>
> What's so upsetting about C++'s approach? You say 'subtyping', but
> that sounds like you're talking about polymorphism again.
> Perhaps it would be better to say 'extending', which is really what it
> is applied to a struct. I think it's a simple and natural syntax to do
> a simple and natural operation like extending a struct.
>
> Look, I'm not actually married to C++'s approach (if you have a better
> idea), but I'm dreadfully bored of D's shitty approach, I've had a
> decade to try and think it's cool, but I actually think it's more shit
> than I thought it was 10 years ago.
> I used to think it was a cool idea; it's a 'cute' use of a novel
> feature in D which achieves a goal... and like, bugger C++ and it's
> stupid face, and anything that's not like C++ is cool, but I was
> wrong. It's a shitty thing to write over and over again and I hate it,
> having done it **A LOT**.
> I haven't generally made a fuss about this like other things because
> it's not a blocker in any way, but it's important to express how bored
> I am of the pattern. It's not better.

Wouldn't it be better to allow structs to implement static only interfaces?

-Alex

June 13, 2019
On Thu, Jun 13, 2019 at 7:55 AM 12345swordy via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> > [...] It's not better.
>
> Wouldn't it be better to allow structs to implement static only interfaces?

I don't know what that means? Like D `interface`, which is a pure vtable with no data members? That's the opposite of what I want... what is a 'static' interface?
June 13, 2019
On Thu, Jun 13, 2019 at 7:35 AM Exil via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> On Thursday, 13 June 2019 at 06:43:44 UTC, Manu wrote:
> > This should obviously be a compile error:
> >   struct A { int x; }
> >   struct B : A { int y; }
> >   B b;
> >   A a = b; // <- obviously an error
>
>
> It doesn't become so obvious when you can implicitly convert to the base type.
>
>      A foo(ref A a) { return a; }
>
>      B b;
>      A a = foo(b);

So don't implicitly convert to the base type?
B extends A, but I don't think it's a kind of A as for polymorphic classes.
June 13, 2019
On Thursday, 13 June 2019 at 22:12:37 UTC, Manu wrote:
> On Thu, Jun 13, 2019 at 7:55 AM 12345swordy via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>>
>> > [...] It's not better.
>>
>> Wouldn't it be better to allow structs to implement static only interfaces?
>
> I don't know what that means? Like D `interface`, which is a pure vtable with no data members? That's the opposite of what I want... what is a 'static' interface?

Interface with only static functions and data members. No virtual function what so ever.
June 13, 2019
On Thu, Jun 13, 2019 at 4:05 PM 12345swordy via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> On Thursday, 13 June 2019 at 22:12:37 UTC, Manu wrote:
> > On Thu, Jun 13, 2019 at 7:55 AM 12345swordy via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
> >>
> >> > [...] It's not better.
> >>
> >> Wouldn't it be better to allow structs to implement static only interfaces?
> >
> > I don't know what that means? Like D `interface`, which is a pure vtable with no data members? That's the opposite of what I want... what is a 'static' interface?
>
> Interface with only static functions and data members. No virtual function what so ever.

Well... right. We're talking about struct's here. struct's don't have virtual functions.