[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: MIT discovered issue with gcc

On Thu, Nov 28, 2013 at 6:10 AM, Wade Richards <wade@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

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 <alvarezp@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

> 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.

Reply to: