4 ms·
The optimisation isn't valid unless the dereference always happens. The criticism arose because this optimisation had been applied in a kernel environment, whe
by caf 8y ago
The optimisation isn't valid unless the dereference always happens.
The criticism arose because this optimisation had been applied in a kernel environment, where the dereference happened before the test, but in some circumstances might not trap. It isn't something that concerns normal applications, though.
- jstimpfle 8y agoI should have researched a better example. But anyways, what about a case like this one? int *p = get_the_pointer(); if (p == NULL) { remove_me(); } printf("Hello %d\n", *p); At least for some things that remove_me() could do, wouldn't it be possible for a compiler to remove the branch entirely? I mean I'm pretty sure that compilers can move the conditional below the printf under certain circumstances (as long as there isn't an observable difference for C's definition of "observable"). Add to that the UB and the compiler might as well remove the conditional branch. (And this would be a case that can really take programmers by surprise when debugging).
- caf 8y agoYes, it depends on whether remove_me() (provably) always returns or not. Optimisations frequently do things that take people by surprise when debugging, but that's par for the course.
- MaxBarraclough 8y ago> Yes, it depends on whether remove_me() (provably) always returns or not. Oops, I hadn't thought of that. So the compiler isn't permitted to assume that a function-call will return? Surely that's a huge obstacle to optimisation.
- caf 8y agoNo, not in general, because it might call longjmp(), exit() or abort(). Opinions are divided in the case where it doesn't return because it enters an infinite loop.
- MaxBarraclough 8y agoInteresting, thanks.
- MaxBarraclough 8y agoYou and caf are right, the compiler can indeed remove the remove_me() call. It is permitted to assume the absence of undefined behavior, so it can 'reason' as you describe. Of course, the compiler can have the code do anything at all, as it's undefined behaviour. In practice, the resulting behaviour can be deeply counterintuitive ('impossible looking' results). > C's definition of "observable" Indeed, which essentially changes meaning when we introduce multithreading. The perceived order of our writes isn't assured to match up to our source-code. The horror-show continues! > And this would be a case that can really take programmers by surprise when debugging Or worse: only in release builds. Not impossible, if you do all your debugging on unoptimised builds, but release optimised builds.