DIP 1006 - Preliminary Review Round 1

Walter Bright newshound2 at digitalmars.com
Mon Mar 5 20:55:24 UTC 2018


On 3/5/2018 7:48 AM, Timon Gehr wrote:
> Again: assert is @safe. Compiler hints are @system. Why should assert give 
> compiler hints?

Asserts give expressions that must be true. Why not take advantage of them? See 
Spec# which based an entire language around that notion:

  https://en.wikipedia.org/wiki/Spec_Sharp

Some possible optimizations based on this are:

1. elimination of array bounds checks
2. elimination of null pointer checks
3. by knowing a variable can take on a limited range of values, a cheaper data 
type can be substituted
4. elimination of checks for 'default' switch values
5. elimination of overflow checks

dmd's optimizer currently does not extract any information from assert's. But 
why shut the door on that possibility?


> But the whole point of having memory safety is to not have UB when the 
> programmer screwed up. Behavior not foreseen by the programmer (a bug) is not 
> the same as behavior unconstrained by the language specification (UB).

It's the programmer's option to leave those runtime checks in if he wants to.


> 'in'-contracts catch AssertError when being composed. How can the language not 
> be designed to support that?

That is indeed an issue. It's been proposed that in-contracts throw a different 
exception, say "ContractException" so that it is not UB when they fail. There's 
a bugzilla ER on this. (It's analogous to asserts in unittests not having UB 
after they fail.)


> - I usually don't want UB in programs I am working on. I want the runtime 
> behavior of the programs to be determined by the source code, such that every 
> behavior observed in the wild (intended or unintended) can be traced back to the 
> source code (potentially in a non-deterministic way, e.g. void initialization of 
> an integer constant). This should be the case always, even if me or someone else 
> on my team made a mistake. The @safe D subset is supposed to give this 
> guarantee. What good is @safe if it does not guarantee absence of buffer overrun 
> attacks?

It guarantees it at the option of the programmer via a command line switch.


> - Using existing assertions as compiler hints is not necessary. (Without having 
> checked it, I'm sure that LDC/GDC have a more suitable intrinsic for this already.)
> 
> As far as I can discern, forcing disabled asserts to give compiler hints has no 
> upsides.

I suspect that if:

     compiler_hint(i < 10);

were added, there would be nothing but confusion as to its correct usage vs 
assert vs enforce. There's already enough confusion about the latter two. In 
fact, I can pretty much guarantee it will be rarely used correctly.


> I know. Actually version(assert) assert(...); also works. However, this is too 
> verbose, especially in contracts.

You can wrap it in a template.


> I'd like a solution that does not require me 
> to change the source code. Ideally, I just want the Java behavior (with reversed 
> defaults).

But you'll have to change the code to compiler_hint().


> (enforce is _completely unrelated_ to the current discussion.)

It does just what you ask (for the regular assert case).


>> It being UB was my doing, not Mathias'. DIP1006 is not redefining the 
>> semantics of what assert does.
> This is not really about assert semantics, this is about the semantics of 
> "disabling the check".

It is very much about the semantics of assert.


> There was no "-check=off" flag before.

Yes there was, it's the "release" flag.


> The DIP uses terminology such as "disable assertions" as opposed to "disable 
> assertion checks (but introduce compiler hints)".

Yes, the language could be more precise, but I couldn't blame Mathias for that. 
I also disagree with the word "hint", because it implies things like "this 
branch is more likely to be taken" to guide code generation decisions, rather 
than "assume X is absolutely always incontrovertibly true and you can bet the 
code on it".



More information about the Digitalmars-d mailing list