4 ms·
The problem is that the language allows this code and the compiler accepts it. If the code really does make no sense, then why not disallow it or capture it wi
by GedByrne 9y ago
The problem is that the language allows this code and the compiler accepts it.
If the code really does make no sense, then why not disallow it or capture it with a compiler warning?
Instead the optimizer is to silently remove the code.
Isn't it possible that the programmer knows something that the optimizer is unaware of?
- deleted 9y ago[deleted]
- Karellen 9y agoThe standard can't mandate a diagnostic for undefined behaviour, because it's not always possible to determine if behaviour is undefined. (Turing completeness) However, an implementation is allowed to issue any diagnostics it likes, so if you want one for this case, bug your compiler vendor to add one. Or, check the manual - it's possible that your compiler already does issue a diagnostic if you turn the right warnings on.
- xorblurb 9y ago> The standard can't mandate a diagnostic for undefined behaviour, because it's not always possible to determine if behaviour is undefined. Yet that argument is stupid if we are talking about compilers issuing warnings for the UB they "detect", because by definition they have detected them. It might not be possible when it does not work exactly like that in some cases, but at least before removing some code, this is desirable. It might also not be easy given the current internal design of compilers, but then I argue those design should be changed, because it is just too dangerous.
- clarry 9y agoYou are free to pave the way. But pretending that compiler developers are currently just ignoring the issue out of mischief and preference for performance above anything else is disingenous. If the problem were so simple, we'd probably already have a dozen free static analyzers that do a good job, and you'd be happy to use them. The thing is, "detecting" UB in the sense you imply is usually not what happens in the context of said optimizations (that's not to say they won't attempt to do it... ever seen a compiler warn you about use of uninitialized variable?). What compilers do is they assume the program is correct. And following that assumption, they perform an optimization that is only correct for correct programs. That is in fact very simple to do. They do not try to prove or disprove that program actually invokes UB there -- that is impossible in general, and even in the subset of cases where it is possible it could require deep whole-program (including libraries!) analysis that could take massive computational resources. Many people here keep trivializing the problem but I don't think they understand the problem at any depth. And that is why I say you should pave the way, not in a smug "fuck off get off my lawn fix your own problem" sense, but to get people to honestly gain some background in program analysis, read research papers, study existing analyzers, and gain some appreciation for what it takes. It is far, far from trivial. Especially if you can't just take the language and change it to your liking (breaking nearly all existing code) until all the hard stuff is out. And in saying that, I suggest that it is easier to start with a new language (or, at least some existing language other than C) that was designed from ground up with such analysis & correctness provability in mind.
- xorblurb 9y agoI might actually end up doing that. But honestly what a waste of resources. I would prefer to be able to work on topics that are not problems created by a recent shift of view of how compiler should be designed and optimize, shift that is for the worst IMO. And yep I know the reason in the current design for why it is not always easy. That's why I added the caveat that maybe they should be changed. But then you can not just says that all the users criticizing and "trivializing" the problem are in the wrong and do not know what they are talking about. First, most of the discussion I've seen either points at technical justification of why those crazy optim should not be done, be it for safety, possibility of real optimizations by the programmers (and to compare, I'm not impress about the capability of compilers to take poor code and to transform it to somehow less poor code, especially when the language in question is C, that always required mastering); or points to discussions of compiler authors that are borderline insane (when you see them discussion about how technically the standards would allow to not consider uint8_t and char as alias, a
- xorblurb 9y agoI might actually end up doing that. But honestly what a waste of resources. I would prefer to be able to work on topics that are not problems created by a recent shift of view of how compiler should be designed and optimize, shift that is for the worst IMO. And yep I know the reason in the current design for why it is not always easy. That's why I added the caveat that maybe they should be changed. But then you can not just says that all the users criticizing and "trivializing" the problem are in the wrong and do not know what they are talking about. First, most of the discussion I've seen either points at technical justification of why those crazy optim should not be done, be it for safety, possibility of real optimizations by the programmers (and to compare, I'm not impress about the capability of compilers to take poor code and to transform it to somehow less poor code, especially when the language in question is C, that always required mastering); or points to discussions of compiler authors who are borderline insane (when you see them discussion about how technically the standards would allow to not consider uint8_t and char as alias, and they ask themselves if they could not "optimize" more thanks to that, you clearly understand they have completely lost it, and that things will end up badly); or points to bugs "exposed" by that class of optims (I would even say introduced, because 1) when your binary have been OK on all your target platforms for a few decades, and a new compiler come and break it for a technicality, it can be argued that regardless of said technicality the problem is mainly with the compiler; and 2) compilers compromise e.g. for technically invalid benchmarks, so they have no credibility when they don't take into account major breakage in major software, they are just acting like spoiled child who just want to do what they want regardless of the consequences). What is never addressed by C/C++ compiler authors and their fan base is why the "nonportable" part of the standard is not taken into consideration anymore. This was the original spirit of UB. NOT: "this will permit EXTRA optimization in abstract compiler code"; the only "optim" were because of differences between target processors, and leaving things UB could yield a better mapping to the instruction sets (a trivial mapping) and it was considered that the programmer knew about them, and could use them when needed. Now there is no mapping anymore. We all have to target the common denominator of all the existing target past, present, even dead ones. The result is a very very very poor language. Unsuitable to more and more things.
- clarry 9y ago> If the code really does make no sense, then why not disallow it or capture it with a compiler warning? You answered your own question: > Isn't it possible that the programmer knows something that the optimizer is unaware of? Here's a fun exercise. Find the best static analyzer you can. Run it on some substantial body of C code. Count all the false positives and false negatives (good luck). Now you should have an idea as to why you can't simply require the compiler to reject the code and issue a diagnostic. But making code like this UB is about as close you can get to "disallowing it." Alternatively you could try to eliminate the problem entirely by removing the whole concept of uninitialized memory and requiring that all variables are initialized to some value per default. Depending on which camp you're in, this is a step forward or a step back. Some people just see the words UB and think it is Satan, bad bad bad. For them this is a step forward. But if all variables are supposed to have a definitive starting value, compilers & static analyzers suddenly can't warn you about the cases where it can tell you forgot to initialize something, because all of a sudden such code is totally legit. The analyzer can't tell whether you forgot to make an initialization or whether you're actually intentionally relying on the default value. That's a big step back as far as I am concerned. You eliminate a problem because "UB is bad!" and create another problem we can't even issue warnings for, without potentially generating loads of false positives. Now if one wanted to complain that his compiler detects an obvious case of UB and doesn't warn him about it, he should take it up with the compiler developers (or see if he can help himself by turning on the right flags). Alternatively one could invest in a good static analyzer. The standard committee can't really fix this problem without making substantial changes to the language. Instead I'm glad they allow relatively simplistic implementations that don't do deep advanced analysis.
- ajanuary 9y agoC# is an example of a language that decided that including definite assignment analysis into the language spec was worth the tradeoff.
- DougBTX 9y ago> Now you should have an idea as to why you can't simply require the compiler to reject the code and issue a diagnostic. It is quite a different beast, but C# produces compile time failures when attempting to read from a potentially uninitialised variable. What is it that makes C different?