June 10, 2019
On 6/10/2019 3:56 PM, Manu wrote:
> Uninitialised data, which is guaranteed to have no valid state, and
> has absolutely no chance of proper program execution under any
> circumstance, and may even be leaking internal/private state(!), is
> not safe. You can't convince me otherwise.

It is memory safe. It's a fact, not an opinion.

If you want @safe to mean "no undefined behavior", that is a valid opinion, but that is not what @safe in D is currently defined as. It is currently defined as "memory safe". If you can find a case where an int with garbage in it can cause memory corruption in @safe code, that would indeed be a bug in D.

> It is arbitrary. Almost everything comes down to "I like this", or "I
> don't like this", and the noise in the middle is mostly a waste of our
> time.

Most of language design is indeed subjective. But things like "memory safety" are fairly well defined in an objective manner.

> Occasionally argument improves outcomes, but for the most part, we're
> all just wasting time here.

Saying "you can't convince me otherwise" guarantees discussing things won't work. :-)
June 10, 2019
On Mon, Jun 10, 2019 at 3:35 PM Max Haughton via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> On Monday, 10 June 2019 at 21:59:51 UTC, Ola Fosheim Grøstad wrote:
> > On Monday, 10 June 2019 at 21:15:52 UTC, Walter Bright wrote:
> >> On 6/10/2019 7:42 AM, Andrei Alexandrescu wrote:
> >>> The same way it causes in C++. Crack open literally any C++ introductory book to find the explanation.
> >>
> >> Some reasons:
> >>
> >> https://stackoverflow.com/questions/4353203/thou-shalt-not-inherit-from-stdvector
> >
> > The answers with high rating actually state that there is no problem in inheriting from std::vector…
> >
> >> https://stackoverflow.com/questions/2034916/is-it-okay-to-inherit-implementation-from-stl-containers-rather-than-delegate
> >
> > The most highly rated answer says that there is no problem with inheriting from std::vector if you don't rely on on having a virtual destructor…
> >
> > So, not the best source for building an argument.
>
> Just because the code is semantically correct or "safe" doesn't mean it's good code. Inheriting from a container that you either aren't directly extending or don't own is a huge code smell in my view

DRY. Base sets of members for consistency and minimising maintenance
between collections of things are unbelievably common.
DRY exists separately from polymorphism.

June 10, 2019
On Mon, Jun 10, 2019 at 5:35 PM Walter Bright via Digitalmars-d <digitalmars-d@puremagic.com> wrote:
>
> On 6/10/2019 3:56 PM, Manu wrote:
> > Uninitialised data, which is guaranteed to have no valid state, and has absolutely no chance of proper program execution under any circumstance, and may even be leaking internal/private state(!), is not safe. You can't convince me otherwise.
>
> It is memory safe. It's a fact, not an opinion.

Consequence may not be. Effect isn't necessarily isolated to this statement.
And you'll retort that that's true for every line of code, even well
formed code... but in this case, we can guarantee without any shadow
off doubt that a program error probably exists, and I want @safe to
mean that.

It also leaks private knowledge, and it's the first place anyone would look to exploit your code. If @safe doesn't do everything it can to assist preventing that sort of attack, especially something so plainly obvious, then it's not doing its job.

> If you want @safe to mean "no undefined behavior", that is a valid opinion, but that is not what @safe in D is currently defined as.

Well it's an unsatisfying or incomplete definition then if it allows for something so obviously unsafe (in english terms) to be considered perfectly fine.

> > Occasionally argument improves outcomes, but for the most part, we're all just wasting time here.
>
> Saying "you can't convince me otherwise" guarantees discussing things won't work. :-)

Right. That's my point. And why I said we shouldn't pull this off topic.
If your definition of safe doesn't allow for the compiler to issue an
error when accessing provably invalid memory, then I don't care for
your definition of @safe.
Users tend not to be language lawyers, they will be surprised by this.

Anyway, that's not on trial here.
June 11, 2019
On Sunday, 9 June 2019 at 13:59:25 UTC, Jonathan M Davis wrote:
> However, if you're using this pattern frequently, what's stopping you from just creating a function or template to use with mixin that takes care of it for you? I would have thought that it would be fairly straightforward to do something like
>
> struct DerivedStruct
> {
>     mixin(aliasAsMember!BaseStruct);
> }
>
> and then it really isn't any more complex than
>
> struct DerivedStruct : BaseStruct
> {
> }
>
> would be.
>
> - Jonathan M Davis

Yes it is!

I do reverse engineering followed by code injection, etc etc. When there are POD types that share a common set of members, simple inheritance saves a whole lot of time.

As an example of usefulness: when some code in the binary you're injected to expects x field to be at y offset, and another function expects that same field to be at the same offset, with the addition of some extra data that the previous function is unaware of, the simple solution is obvious: inherit a base structure that contains the common members.

It also reduces the need for workarounds when using types and non-assembly callable function declarations.

Because D does not afford that luxury, I frequently have to choose a language like C++ for the sake of *maintenance* (hah!), and that sucks.
June 11, 2019
On Tuesday, 11 June 2019 at 01:23:29 UTC, SonicFreak94 wrote:
> On Sunday, 9 June 2019 at 13:59:25 UTC, Jonathan M Davis wrote:
>> However, if you're using this pattern frequently, what's stopping you from just creating a function or template to use with mixin that takes care of it for you? I would have thought that it would be fairly straightforward to do something like
>>
>> struct DerivedStruct
>> {
>>     mixin(aliasAsMember!BaseStruct);
>> }
>>
>> and then it really isn't any more complex than
>>
>> struct DerivedStruct : BaseStruct
>> {
>> }
>>
>> would be.
>>
>> - Jonathan M Davis
>
> Yes it is!
>
> I do reverse engineering followed by code injection, etc etc. When there are POD types that share a common set of members, simple inheritance saves a whole lot of time.
>
> As an example of usefulness: when some code in the binary you're injected to expects x field to be at y offset, and another function expects that same field to be at the same offset, with the addition of some extra data that the previous function is unaware of, the simple solution is obvious: inherit a base structure that contains the common members.
>
> It also reduces the need for workarounds when using types and non-assembly callable function declarations.
>
> Because D does not afford that luxury, I frequently have to choose a language like C++ for the sake of *maintenance* (hah!), and that sucks.

You can do this with structs and alias this now. I also doubt code injection is something a language should consider for its use cases. It is only really useful for a niche.

June 11, 2019
On Tuesday, 11 June 2019 at 01:33:58 UTC, Exil wrote:
> You can do this with structs and alias this now. I also doubt code injection is something a language should consider for its use cases. It is only really useful for a niche.

Convenient, with the caveat that one must add that as a field manually and then add another line to alias it. Two D lines for the functionality of one in C++, just so that I can share members...
June 11, 2019
If the main objection to

struct DerivedStruct : BaseStruct
 {
     // derived members
     //...
 }

looks too much like polymorphism

would something like
struct DerivedStruct
{
     @contains BaseStruct base;
}
with some creative lowering
be a more acceptable way forward?
June 11, 2019
On Tue, Jun 11, 2019 at 12:08 PM Danni Coy <danni.coy@gmail.com> wrote:
>
> If the main objection to
>
> struct DerivedStruct : BaseStruct
>  {
>      // derived members
>      //...
>  }
>
> looks too much like polymorphism
>
> would something like
> struct DerivedStruct
> {
>      @contains BaseStruct base;
> }
> with some creative lowering
> be a more acceptable way forward?

or alternatively
struct DerivedStruct : static BaseStruct
{
}
June 10, 2019
On Monday, June 10, 2019 6:30:27 PM MDT Walter Bright via Digitalmars-d wrote:
> On 6/10/2019 3:56 PM, Manu wrote:
> > Uninitialised data, which is guaranteed to have no valid state, and has absolutely no chance of proper program execution under any circumstance, and may even be leaking internal/private state(!), is not safe. You can't convince me otherwise.
>
> It is memory safe. It's a fact, not an opinion.
>
> If you want @safe to mean "no undefined behavior", that is a valid opinion, but that is not what @safe in D is currently defined as. It is currently defined as "memory safe". If you can find a case where an int with garbage in it can cause memory corruption in @safe code, that would indeed be a bug in D.

It was my understanding that having no undefined behavior was required to be able to guarantee memory safety, since without that, the compiler could potentially reorder or optimize code in a way that violated memory safety (because undefined behavior lets the compiler do pretty much whatever it wants with that piece of code). Regardless of whether that's true or not however, the spec _does_ state that @safe functions don't have undefined behavior. In fact, surpisingly, the primary section on @safe functions says that without saying anything about memory safety:

https://dlang.org/spec/function.html#function-safety

- Jonathan M Davis



June 11, 2019
On Monday, 10 June 2019 at 22:56:50 UTC, Manu wrote:
> On Mon, Jun 10, 2019 at 2:55 AM Walter Bright via Digitalmars-d
>
> You can't convince me otherwise.

Discussions are meant to understand, not to convince ...