On Thu, Nov 28, 2013 at 6:10 AM, Wade Richards <w...@wabyn.net> wrote: > One of the links Mark posted earlier addresses the "The compiler should > issue warnings" issue. The short answer is because of macro expansion and > other code-rearranging optimizations (inlining functions, loop unrolling, > pulling expressions out of a loop, etc.), undefined code appears and is > removed more often than you'd expect. Issuing a warning *every time* this > happens would generate many confusing warnings that users wouldn't like.
I'm taking a course in embedded programming at the local employment training center to "brush up" on skills I never lost, for reasons that I won't bother to explain. The teacher during the interview to C, when introducing pointers, was about to tell the students to not bother introducing a pointer to an eight byte array of characters because that wasn't enough memory to worry about. And I'm sitting here remembering the business about dereferencing the NULL pointer, and sysads leaving the bottom page of RAM allocated and active to keep "running" code "running". The problem has been mentioned elsewhere in this thread, I think. But we aren't looking at it straight. Silently dropping code that produces code that is not defined within the standard is very similar to silently leaving a page allocated at the lowest addresses. ** Silently ** is the problem. If programmers get used to using the bottom page of RAM as an implicitly allocated volatile but temporary storage area, that becomes part of the defacto standard, and if the 800 pound gorilla decides it should then become part of the formal standard, who's to argue? If programmers get used to saying things they don't mean because the compiler silently optimizes it away because it's not defined according to the standard, they learn to misunderstand the code they produce. That's not good, is it? > Also, the deeper you get into the optimized code, the harder it is to issue > meaningful source-level warnings. E.g. when the compiler optimizes: Even unintelligible error messages would be better than silence. You can interpret the old story about Ariane 5 in many ways, but I'm thinking that silently optimizing improper code away doesn't help systems to not crash. > static int decimate(x) { return x/10; } > int foo() { > int a=INT_MAX; > int b; > for(i=0; i<100; ++i) { b=max(i, decimate(a*10));} Why are we expecting the compiler to optimize that away for us? Undefined behavior and system dependent behavior are two separate things. Conflating them in the standard is going to lead to more Ariane 5 kinds of crashes. Anyway, if we can go deep enough in the optimizations to "see" that it hits undefined behavior, going far enough to emit a warning is the responsible behavior, not punting. > return b; > } > > > into > > int foo() { return INT_MAX; } > > > What warnings should appear for which lines? Optimizing it in the way you suggest is not the same as optimizing out undefined behavior. There is, in fact, no reason to expect the compiler to convert it in the way you suggest over some other conversions. However, to work with your example, my naive intuition would suggest that the first warning would be in the call to decimate( a * 10 ), in other words, the familiar "significance lost in expression" could be augmented with something like "for initial value" and then ", may produce unintended results." Or, for something new and friendly, "Saturation on this processor results in invariant result of looped expression. Check that this is an acceptable optimization." > http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html (third > page). > > --- Wade > > > On Nov 27, 2013, at 12:19, Octavio Alvarez <alvar...@alvarezp.ods.org> > wrote: > > On 26/11/13 11:37, Mark Haase wrote: > > Compiler developers, for better or worse, reserve the right to do > > whatever they want with undefined behavior, and it's up to the person > > writing the C code to not include undefined behavior in their own program. > > > That's a fallacy. It is, indeed, a fallacy, conflating an false argument with a result of false. > The fact that a compiler does not violate the standard > does not imply it is behaving sane. Thus, not violating the standard does > not imply not having a bug. > > Considering a programmer would not ever *ever* want to fall into undefined > behavior, the compiler should just issue warnings before making any kind of > assumptions based after undefined behavior. Those warnings could be silenced > with flags. This is a way of "yes, I'm sure of what I'm doing". > > Therefore, a Linux distribution has 2 choices: (1) wait for upstream > > patches for bugs/vulnerabilities as they are found, or (2) recompile all > > packages with optimizations disabled. I don't think proposal #2 would > > get very far... And, according to the article that started this thread, isn't going to do the job, either, since many of our primary compilers now optimize more than they are able to warn about even at the lowest level of optimization. > What about adding cppcheck warnings and gcc -Wall -pedantic be added to > Lintian? > > Or what about changing debhelper to pass some -f flags by default? I'm thinking the standards committee needs some fresh blood. It's well past time for the standard to recognize the difference between undefinable behavior and system dependent behavior, and to encourage compiler writers to put warnings about system dependent behavior at a higher priority than arbitrary optimizations. -- Joel Rees Be careful where you see conspiracy. Look first in your own heart. -- To UNSUBSCRIBE, email to debian-security-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org Archive: http://lists.debian.org/CAAr43iN9vzx63g0vOdFLbtGq24St42-X=29q1u8zjgo2jpf...@mail.gmail.com