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