5 ms·
There is no requirement that optimization does not change behaviour. The only requirement is that the optimized behavior remains consistent with the standards.
by gizmo686 8y ago
There is no requirement that optimization does not change behaviour. The only requirement is that the optimized behavior remains consistent with the standards. The point of the point on floating point equality is that the standards give enough room for variance that you should not use literal equality unless you know exactly what you are doing and have a good reason for doing it.
As an aside, if your concern is that the standards impose too much restrictions, another popular option is the ffast-math option.
We see this come up with strings fairly often in higher level languages where, sometimes, logical equal strings will happen to be equal because the runtime's interning system made them point to the same location, but there is no guarantee this would happen and the implementation is free to change it at any point. I believe I have also seen this behaviour come up with interning on some Integer wrapper types.
- loeg 8y ago> I believe I have also seen this behaviour come up with interning on some Integer wrapper types. Python, for example: >>> 8 is 8 True >>> 8**1000 is 8**1000 False
- olliej 8y agoBecause python is broken in this respect -- JS engines do exactly the same object optimisations and get comparisons correct.
- loeg 8y agoMeh. They're different languages with different expectations. "is" is distinct from "==" in both, and Python gets "==" right (obviously). Javascript doesn't really have any high ground here[0]. (In contrast, Python:) >>> [] == False False >>> object() == False False >>> "" == False False >>> {} == False False They're just different. [0]: https://www.youtube.com/watch?v=et8xNAc2ic8 https://www.youtube.com/watch?v=et8xNAc2ic8
- viraptor 8y agoJS has "strict equality" comparison. It's not the same as "identity" comparison.
- olliej 8y agoNo, optimizations are allowed to change the ordering or exact implementations, but they cannot change observable behavior unless the behavior depends on undefined (e.g the compiler is the adversary) or unspecified (in which the compiler is required to be self-consistent, e.g parameter evaluation order is (was?) unspecified so a compiler could choose left to right or right to left evaluation, but it must pick one and use that everywhere). The C abstract machine defines the behavior, and optimization passes aren't allowed to change the behavior. -ffast-math is the option that allows incorrect semantics (e.g commutative floating point addition), but compilers have a desire to do incorrect things for "performance". I would hope it is obvious that changing behavior for performance isn't ok, but lets say it was. A compiler could change y=1.0/fsqrt(x) from (v. approximate, untested, and written in a text box :D) movsd xmm0, $(wherever x is) sqrtsd xmm0 movsd xmm1, $(location of 1.0 constant) divsd xmm1, xmm0 movsd $(addr of y), xmm1 to something like movsd xmm0, $(wherever x is) rsqrtsd xmm0 movsd $(addr of y), xmm0 This would be much much faster, and vastly incorrect (IIRC rsqrt is only 12bits of precision) Or even more dumb, remove calls to printf, because printf is slow. A compiler does not have absolute leeway in all things, it is still restricted to ensuring that observable results of the C abstract machine are correct.