status of D optimizers benefiting from contracts ?

bearophile via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Mon Nov 10 02:27:18 PST 2014


Meta:

> On the other hand, making assert a built-in that provides 
> optimization hints has been proposed for C++17:

Thank you for the link.


> http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2014/n4154.pdf

But that behavour is on request (using NDEBUG = strong), it's not 
suddenly becoming the default for D as Walter suggested:

<<
To satisfy as many users as possible, four levels of assertion 
are provided:	
• Default: assert evaluates its condition and generates a 
diagnostic upon failure.	
• NDEBUG = strong: assert has no side effects, but the 
implementation may use the
condition, and if it would fail, the behavior is undefined. This 
provides optimal hints.	
• NDEBUG = strict: The assert expression is fully parsed and 
semantically checked,
but no evaluation occurs. The behavior is still defined even if it 
would evaluate as false, but
this may be considered unlikely.	
• NDEBUG defined as empty or an integer literal: The assert 
operands are syntactically a
balanced-token-seq. Otherwise this is the same as strict mode.	
• Other identifiers in the expansion of NDEBUG are reserved to the 
standard for future
expansion, except for identifiers usually reserved to the library.
>>

If you write a program from the start using NDEBUG=strong you are 
relying on a different semantics for assert. It's essentially a 
different kind of assert. You can't take D programs and silently 
change the basic semantics of all asserts under them. And still, 
in many cases you don't want to use NDEBUG=strong, that's why 
there are also other available behaviours like NDEBUG=strict that 
is an intermediate point.

I think this proposal n4154 is a bit over-engineered (as it often 
happens to C++), but it avoids most of the faults in Walter 
ideas: it avoids breaking existing code (because the default 
behavour doesn't change), allows optimizations on request, etc.

In practice I prefer to avoid using hacks like setting a NDEBUG. 
It's better to have differently named operators if their behavour 
is different. So it's better to keep the assert() as it is 
commonly used (and I'd like it to refuse a not pure expression). 
And add another operator, like strong_assert() for the 
NDEBUG=strong behavour. (And if you can't live with it, you can 
also add a strict_assert()). Changing the behavour of asserts 
just changing a global constant is silly because what matters is 
the semantics the programmer gives to the assert he/she/shi is 
using. So giving them different names is much better.

Walter is right in his very strong engineer desire to keep 
designs as simple as possible; but often giving the same name to 
things with different semantics doesn't reduce the complexity, it 
just increases the confusion. I greatly prefer when things with 
different semantics have cleanly distinct names.

Bye,
bearophile


More information about the Digitalmars-d-learn mailing list