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".

Reply via email to