April 10, 2014
On Thursday, 10 April 2014 at 18:13:30 UTC, Steven Schveighoffer wrote:
> On Thu, 10 Apr 2014 14:08:48 -0400, Tommi <tommitissari@hotmail.com> wrote:
>
>> On Thursday, 10 April 2014 at 17:56:04 UTC, Steven Schveighoffer wrote:
>>> @safe code can be marked as @trusted instead, and nothing changes, except @trusted code can have bounds checks removed. How does this not work as a solution?
>>
>> A compiler flag for disabling bounds checking is a blunt instrument. But using search & replace to change each @safe to @trusted is a blunt _and_ inconvenient instrument.
>
> So don't use it bluntly. For example, disabling bounds checks on the args array in main will not help your performance.

Sometimes you need that blunt instrument. I wasn't complaining about that.

> As a general rule, first profile, then optimize.

Exactly. I profile the difference between running with and without bounds checking. If the difference is deemed negligible for our purposes, we don't spend time and money in carefully optimizing away bound checks that are analyzed to be reasonably safe to remove. You need the compiler flag to potentially save you all the trouble.
April 10, 2014
On Thu, 10 Apr 2014 15:38:37 -0400, Tommi <tommitissari@hotmail.com> wrote:

> On Thursday, 10 April 2014 at 18:13:30 UTC, Steven Schveighoffer wrote:
>> As a general rule, first profile, then optimize.
>
> Exactly. I profile the difference between running with and without bounds checking. If the difference is deemed negligible for our purposes, we don't spend time and money in carefully optimizing away bound checks that are analyzed to be reasonably safe to remove. You need the compiler flag to potentially save you all the trouble.

This is a weak argument. If you need to optimize, do it. Bounds checking is one of a thousand different possible explanations for slow code. You have to weigh that remote possibility with the threat of accidentally/inadvertently neutering @safe.

You also exaggerate the cost of changing a few @safe to @trusted. The cost of adding the -noboundscheck flag to the build system in the right places may be just as significant.

-Steve
April 10, 2014
On Thursday, 10 April 2014 at 19:48:16 UTC, Steven Schveighoffer wrote:
> On Thu, 10 Apr 2014 15:38:37 -0400, Tommi <tommitissari@hotmail.com> wrote:
>
>> On Thursday, 10 April 2014 at 18:13:30 UTC, Steven Schveighoffer wrote:
>>> As a general rule, first profile, then optimize.
>>
>> Exactly. I profile the difference between running with and without bounds checking. If the difference is deemed negligible for our purposes, we don't spend time and money in carefully optimizing away bound checks that are analyzed to be reasonably safe to remove. You need the compiler flag to potentially save you all the trouble.
>
> This is a weak argument. If you need to optimize, do it. Bounds checking is one of a thousand different possible explanations for slow code. You have to weigh that remote possibility with the threat of accidentally/inadvertently neutering @safe.
>
> You also exaggerate the cost of changing a few @safe to @trusted. The cost of adding the -noboundscheck flag to the build system in the right places may be just as significant.
>
> -Steve

Okay, I give up. You win this debate. Let's prevent D programmers from removing bounds checks from their programs with a compiler flag.
April 10, 2014
On 04/10/2014 07:37 PM, Steven Schveighoffer wrote:
>>
>
> That's why we have @trusted. @safe is a special situation, it's not made
> for optimization, and should be immune to those attempts in deference to
> safety.
>
> -Steve

@safe will often be inferred.
April 10, 2014
On Thu, 10 Apr 2014 16:06:28 -0400, Timon Gehr <timon.gehr@gmx.ch> wrote:

> On 04/10/2014 07:37 PM, Steven Schveighoffer wrote:
>>>
>>
>> That's why we have @trusted. @safe is a special situation, it's not made
>> for optimization, and should be immune to those attempts in deference to
>> safety.
>>
>> -Steve
>
> @safe will often be inferred.

A good point. But in this case, the compiler is able to compile 2 versions, one for when @safe is required, one for when it's not. But this is only in certain circumstances (global bounds checking is not on, the function is not inlined, code which causes bounds checking is present, etc.)

-Steve
April 10, 2014
On Thursday, 10 April 2014 at 19:48:16 UTC, Steven Schveighoffer wrote:
> On Thu, 10 Apr 2014 15:38:37 -0400, Tommi <tommitissari@hotmail.com> wrote:
>
>> On Thursday, 10 April 2014 at 18:13:30 UTC, Steven Schveighoffer wrote:
>>> As a general rule, first profile, then optimize.
>>
>> Exactly. I profile the difference between running with and without bounds checking. If the difference is deemed negligible for our purposes, we don't spend time and money in carefully optimizing away bound checks that are analyzed to be reasonably safe to remove. You need the compiler flag to potentially save you all the trouble.
>
> This is a weak argument. If you need to optimize, do it. Bounds checking is one of a thousand different possible explanations for slow code. You have to weigh that remote possibility with the threat of accidentally/inadvertently neutering @safe.
>
> You also exaggerate the cost of changing a few @safe to @trusted. The cost of adding the -noboundscheck flag to the build system in the right places may be just as significant.
>
> -Steve

Changing druntime and phobos is a much bigger deal than a flag.

In a perfect world I'd agree with you completely but as a practical matter I think the flag needs to stay.

There is also an issue of marketing (as annoying as it is). This problem is reminiscent of the garbage collector argument against D. For far too many people D is a no-go simply because it has a garbage collector. In reality the garbage collector isn't a problem for the overwhelming majority of use cases but many people will never use the language for this reason.

If someone wants to be reckless and turn off the compiler adding bounds checking in @safe code D should allow them to. It is a systems programming language, after all. Being allowed to be reckless and even stupid is a hallmark of that. That doesn't mean we can't guide people to make smart choices though. -release will always do bounds checking on @safe functions.

How about a compromise? A stern warning is given whenever someone compiles with -boundscheck=none (-noboundscheck). One that stresses they should benchmark before commit to turning it off and that it should only be used as a last resort.
April 10, 2014
On Thu, 10 Apr 2014 16:13:17 -0400, Brad Anderson <eco@gnuk.net> wrote:

> On Thursday, 10 April 2014 at 19:48:16 UTC, Steven Schveighoffer wrote:
>> On Thu, 10 Apr 2014 15:38:37 -0400, Tommi <tommitissari@hotmail.com> wrote:
>>
>>> On Thursday, 10 April 2014 at 18:13:30 UTC, Steven Schveighoffer wrote:
>>>> As a general rule, first profile, then optimize.
>>>
>>> Exactly. I profile the difference between running with and without bounds checking. If the difference is deemed negligible for our purposes, we don't spend time and money in carefully optimizing away bound checks that are analyzed to be reasonably safe to remove. You need the compiler flag to potentially save you all the trouble.
>>
>> This is a weak argument. If you need to optimize, do it. Bounds checking is one of a thousand different possible explanations for slow code. You have to weigh that remote possibility with the threat of accidentally/inadvertently neutering @safe.
>>
>> You also exaggerate the cost of changing a few @safe to @trusted. The cost of adding the -noboundscheck flag to the build system in the right places may be just as significant.
>>
>> -Steve
>
> Changing druntime and phobos is a much bigger deal than a flag.

It's not a flag, it's possibly rebuilding druntime/phobos in an unapproved way.

-Steve
April 10, 2014
On 10.4.2014 19:12, Steven Schveighoffer wrote:
> void foo(T)(T[] x) @safe
> {
>    x[5] = 3;
> }

Is this common practice ? I'd wouldn't call it a safe design. There should be a length check or version check:

version(D_NoBoundsChecks) static assert(0, "bounds checking required");

But I get your point, I have always thought of bounds checking like an optional safety net, you think of it like a required feature.

-- 
mk
April 10, 2014
On 4/10/14, 10:56 AM, Steven Schveighoffer wrote:
> @safe code can be marked as @trusted instead, and nothing changes,
> except @trusted code can have bounds checks removed. How does this not
> work as a solution?

Doesn't work because @trusted removes all additional checks by the compiler. We do want to have @safe as mechanically verified.

> As Walter often says about logical const, logical @safe is @safe by
> convention, and it loses all of its teeth.

I think you are wrong here.


Andrei

April 11, 2014
On Thu, 10 Apr 2014 18:54:57 -0400, Martin Krejcirik <mk-junk@i-line.cz> wrote:

> On 10.4.2014 19:12, Steven Schveighoffer wrote:
>> void foo(T)(T[] x) @safe
>> {
>>    x[5] = 3;
>> }
>
> Is this common practice ? I'd wouldn't call it a safe design.
>

No, this isn't common practice. It's a demonstration of how @safe code can become un-@safe when compiled independent of the original author. In reality, nobody should rely on a bounds check to catch out of bounds conditions (I think it's an Error anyway -- a non-recoverable situation). But memory bugs in safe code should be caught, at compile time if possible, at runtime if not.

> There
> should be a length check or version check:
>
> version(D_NoBoundsChecks) static assert(0, "bounds checking required");
>
> But I get your point, I have always thought of bounds checking like an
> optional safety net, you think of it like a required feature.

It is a safety net, but not optional for @safe code. The promise of @safe is that you CANNOT have a memory corruption error. To break the promise without the knowledge of the code is an incorrect plan, IMO. When you write @safe, it means "this code is memory safe, even if it has bugs."

Perhaps Andrei and Walter feel differently. I don't know.

-Steve