December 09, 2022
On Friday, 9 December 2022 at 12:57:48 UTC, Adam D Ruppe wrote:
> On Friday, 9 December 2022 at 03:40:56 UTC, Walter Bright wrote:
>> Bounds checking is always done
>
> As long as you never use -release!

Should never be used regardless of what you do! It's broken and misleading.
December 09, 2022
On 12/9/2022 5:03 AM, bauss wrote:
> On Friday, 9 December 2022 at 12:57:48 UTC, Adam D Ruppe wrote:
>> On Friday, 9 December 2022 at 03:40:56 UTC, Walter Bright wrote:
>>> Bounds checking is always done
>>
>> As long as you never use -release!
> 
> Should never be used regardless of what you do! It's broken and misleading.

Bounds checking is not disabled with -release
December 09, 2022
On 12/8/2022 3:30 PM, Timon Gehr wrote:
> I hope the answer is just that the reason is that C does it this way.

Yes.
December 09, 2022
On Fri, Dec 09, 2022 at 02:22:36PM -0800, Walter Bright via Digitalmars-d wrote:
> On 12/9/2022 5:03 AM, bauss wrote:
> > On Friday, 9 December 2022 at 12:57:48 UTC, Adam D Ruppe wrote:
> > > On Friday, 9 December 2022 at 03:40:56 UTC, Walter Bright wrote:
> > > > Bounds checking is always done
> > > 
> > > As long as you never use -release!
> > 
> > Should never be used regardless of what you do! It's broken and misleading.
> 
> Bounds checking is not disabled with -release

According to `dmd -h`, they are disabled everywhere except @safe code. That's still a pretty wide area where things could go wrong.  And arguably, @system code is precisely where you WANT to have bounds checks.


T

-- 
A program should be written to model the concepts of the task it performs rather than the physical world or a process because this maximizes the potential for it to be applied to tasks that are conceptually similar and, more important, to tasks that have not yet been conceived. -- Michael B. Allen
December 09, 2022
On Friday, 9 December 2022 at 01:55:22 UTC, Walter Bright wrote:
> On 12/8/2022 4:24 PM, deadalnix wrote:
>> I do not expect this to be that expensive. It is simpler than the escape analysis that is being baked in the language right now, and roughly on par with keeping track of constructors/destructors.
>
> I've done it. It's expensive. It is not on par with ctors/dtors which rely on FILO scope analysis, not data flow.
>
> D's borrow checker does do DFA, and it's slow, and one of the reasons why it's active only with @live annotations. Rust uses DFA, and is notoriously slow.
>
> D always initializes variables, and then the (optional) optimization pass removes the unneeded ones. This is a reasonable approach.

I would suggest that the way to was done probably wasn't the right way. Knowing how DMD works, I suspect this is done on an AST representation, and this is definitively hard to do it on such representation. This is much easier to do on an SSA or Sea of Node style representation.

It's fairly easy to convince oneself this is fast, any modern JIT does it.
December 11, 2022
On 12/9/2022 2:49 PM, deadalnix wrote:
> I would suggest that the way to was done probably wasn't the right way. Knowing how DMD works, I suspect this is done on an AST representation, and this is definitively hard to do it on such representation. This is much easier to do on an SSA or Sea of Node style representation.
> 
> It's fairly easy to convince oneself this is fast, any modern JIT does it.

D's optimizer runs on the intermediate code, not the AST. It's as fast as it's going to get, but is still slow enough that the optimizer is enabled only with a switch.

(The optimizer was built in the DOS days, and you can bet I spent a great deal of time trying to speed it up. It had to work in reasonable time for 16 bit computers. It uses the bit vector approach, recommended by Hennessy&Ullman for optimization algorithms.)

Modern jits work on demand (that's why they're called "Just In Time"), one function at a time, which spreads the time spent optimizing out to the point where one doesn't notice it so much. A native compiler does the *entire program* at the same time.
December 11, 2022
On 12/9/2022 2:39 PM, H. S. Teoh wrote:
> According to `dmd -h`, they are disabled everywhere except @safe code.

Safe code is where bounds checking is needed.

> And arguably, @system code is precisely where you WANT to have bounds
> checks.

Use of @system code should be minimized and in it you're allowed to do whatever you want.

December 12, 2022
On Friday, 9 December 2022 at 22:22:36 UTC, Walter Bright wrote:
>
> Bounds checking is not disabled with -release

//compile with: -release (and see what happens)

module test;

import std.stdio;

void main()
{

    int[5] array = [0, 1, 2, 3, 4];

    for (size_t i = 0; i < array.length + 1; i++)
        writeln("Element ", i, " = ", array[i]);

}


December 12, 2022
On Monday, 12 December 2022 at 03:48:26 UTC, Walter Bright wrote:
> On 12/9/2022 2:39 PM, H. S. Teoh wrote:
>> According to `dmd -h`, they are disabled everywhere except @safe code.
>
> Safe code is where bounds checking is needed.

True, it's needed in @safe, but possibly warranted nonetheless in @system as well.

Of course bounds checking at runtime will always degrade performance.

So the question for @system code - which presumably is being written and optimised for performance (over safety), is whether the developer(s) can be bothered measuring the performace impact of run-time bounds checks, and then, if they can be bothered, subsequently deciding whether that performace impact is sufficient to do away with the memory related safety guarantees provided by those run-time bounds checks.

My guess is developers writing @system code will not even bother to measure - and thus the cycle goes: on and on and on..

December 12, 2022
On Monday, 12 December 2022 at 05:06:06 UTC, youSureAboutThat wrote:
>

just to clarify -> when @safe isn't safe:


module test;

import std.stdio;

// so -boundscheck=off will always disable runtime boundscheck,
// regardless of whether code is annotated as @safe, @system, or @trusted.

// -release will disable runtime boundscheck for code annotated as @trusted and @system
// however, code annotated with @safe will still have runtime boundscheck enabled.

// here is where it's a little tricky...
// calling code annotated with @trusted from code annotated with @safe (see below).

@safe void main() { foo(); } // even though this is marked as @safe
                             // when you compile with -release
                             // boundscheck is disabled for foo()
                             // since foo() is marked as @trusted
                             // and -release removes boundscheck
                             // for @trusted and @system..(but not @safe)

@trusted foo()
{
    int[5] array = [0, 1, 2, 3, 4];

    for (size_t i = 0; i < array.length + 1; i++)
        writeln("Element ", i, " = ", array[i]);
}