3 ms·
Well, what benefit does -fdelete-null-pointer-checks bring? Why would I ever want to remove that check? The more conservative version either segfaults or (quite
by iainmerrick 8y ago
Well, what benefit does -fdelete-null-pointer-checks bring? Why would I ever want to remove that check? The more conservative version either segfaults or (quite likely) accidentally does the right thing. That situation is not great but it’s better than nothing. The fancy optimization just makes a not-great situation much worse.
I agree, it would be best if the compiler rejected this as clearly incorrect code. I think that needs a change in the spec relating to undefined behavior, though (and more importantly a change in direction from compiler vendors).
Edit to add: your second example, type aliasing, is a good one too. I think that one could also be usefully addressed by a compiler that flags it as a likely error. Although you’d need some way to annotate the code in the event that the weird aliasing behavior is actually correct and expected (I dunno, make “len” volatile or something?)
- geofft 8y ago> Well, what benefit does -fdelete-null-pointer-checks bring? Why would I ever want to remove that check? The more conservative version either segfaults or (quite likely) accidentally does the right thing. That situation is not great but it’s better than nothing. My concern is largely about how to phrase "The compiler may not delete this dead code" in a way that's meaningful. For instance, I assume the intent of the proposal is not to forbid optimizing this code in the obvious way, right? int n = param->length, i; if (param == NULL) { return; } if (param == NULL) { return; } for (i = 0; i < n; i++) { do_something(param->data[i]); } What about this? int n = param->length, i; for (i = 0; i < n; i++) { if (param == NULL) { return; } do_something(param->data[i]); } which is more likely to show up in the form of an inline function that checks for NULL - can the compiler refactor that check into a single one? > I think that one could also be usefully addressed by a compiler that flags it as a likely error. The compiler can't know when compiling that one function whether src->len and dest->data alias. It might be compiling that file as a standalone object file, with no other context about who's calling it. Should it emit a warning when compiling that code? (What's the warning, "I'd like to optimize this but I can't?") Alternatively, should it flag the function ... somehow ... so that when someone else calls it with aliasing arguments, that's an error? That isn't even a capability available to the C language as written: it's valid to call that function knowing nothing other than the struct definition and the function's prototype. You can imagine a language where variables carried information about whether they alias. (Actually you don't really have to imagine; the `restrict` keyword does a subset of this in C itself, and other languages have much more explicit ways of tracking this, such as Rust's shared vs. mutable references.) But it would be hard to retrofit such a thing onto existing C code. The fundamental problem with the C language working group is that they're obligated to keep working on C as it already exists.
- iainmerrick 8y agoWhat's the warning, "I'd like to optimize this but I can't?" Yes, that's exactly what I had in mind! :)
- geofft 8y agoMy instinctive response was going to be "That can't work, there are too many of them," but apparently you can do this particular one with -Wnull-dereference (which requires -fdelete-null-pointer-checks enabled to work, but you can just compile twice, once as a throwaway and once for production with -fno-delete-null-pointer-checks, or do the former for non-release builds, or something). More generally, it might be the case that enough of the last several years of unpopular optimizations are controlled by flags that you can compile the code twice, once with the optimization enabled and once without, and warn whenever the optimization changes something. It might even be possible to do this with a shell script that treats the compiler as a black box with -ffunction-sections and uses objdump or something. I do wonder how hard it is to write code that produces the same object code regardless of something more major like -ftrapv, though.
- Asooka 8y agoMy view is that the compiler cannot remove any of these NULL checks. There should be a separate tool that gives the programmer hints that she is making unneeded checks and suggest program transformations, but removing NULL checks is unsafe when done automatically. Because I might be on a platform where param->length is actually referring to valid memory, so my program won't segfault and the NULL check is the only way to know.
- geofft 8y agoThe compiler can't remove repeated NULL checks and collapse them to a single one?? Why?
- vyodaiken 8y agoa) these are marginal optimizations, at best. b) because it violates C practice. My parsing library is written to distrust inputs so as to protect against buffer exploits. Your compiler "optimizes" away my security check because some buggy code dereferences a null pointer - which actually works in this implementation. Great. Now you have "optimized" to create a security hole in the program by removing a single instruction that is actually free in many pipelined architectures. Wonderful. Thanks so much.