UB in D

deadalnix via Digitalmars-d digitalmars-d at puremagic.com
Mon Jul 11 11:47:05 PDT 2016


On Saturday, 9 July 2016 at 23:44:07 UTC, H. S. Teoh wrote:
> I find this rather disturbing, actually.  There is a fine line 
> between taking advantage of assert's to elide stuff that the 
> programmer promises will not happen, and eliding something 
> that's defined to be UB and thereby resulting in memory 
> corruption.
>
> [...]
>
>
> T

While I understand how frustrating it looks, there is simply no 
other way around in practice. For instance, the shift operation 
on x86 is essentially :

x >> (y & ((1 << (typeof(x).sizeof * 8)) - 1))

But will differs on other plateforms. This means that in 
practice, the compiler would have to add bound checks on every 
shift. The performance impact would be through the roof, plus, 
you'd have to specify what to do in case of out of range shift.

Contrary to popular belief, the compiler do not try to screw you 
with UB. There is no code of the form "if this is UB, then so 
this insanely stupid shit". But what happen is that algorithm A 
do not explore the UB case - because it is UB - and just do 
nothing with it, and algorithm B on his side do not check care 
for UB, but will reuse results from A and do something unexpected.

In Andrei's example, the compiler won't say, fuck this guy, he 
wrote an UB. What will happen is that range checking code will 
conclude that 9 >> something must be smaller than 10. The the 
control flow simplification code will use that range to conclude 
that the bound check must be always true and replace it with an 
unconditional branch.

As you can see the behavior of each component here is fairly 
reasonable. However, the end result may not be.


More information about the Digitalmars-d mailing list